Skip to content

Commit ea8a0aa

Browse files
committed
go with a less confusing api for optionals
we shoudl just stick to guarding, no extra stuff to make it seem less complicated
1 parent 699e39e commit ea8a0aa

File tree

2 files changed

+103
-270
lines changed

2 files changed

+103
-270
lines changed

Sources/MightFail/MightFail.swift

Lines changed: 103 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// MARK: - Maybe With Success
12

23
/// Executes a throwing function and returns a tuple containing the error (if any), the result (if successful), and a boolean indicating success.
34
///
@@ -20,11 +21,17 @@
2021
/// try fetchData()
2122
/// }
2223
///
23-
/// if success {
24-
/// print("Data fetched successfully: \(data!)")
25-
/// } else {
24+
/// guard let data else {
2625
/// print("Failed to fetch data. Error: \(error)")
26+
/// return
2727
/// }
28+
/// // or
29+
/// guard success else {
30+
/// print("Failed to fetch data. Error: \(error)")
31+
/// return
32+
/// }
33+
///
34+
/// print("Data fetched successfully: \(data)")
2835
/// ```
2936
@inlinable
3037
public func mightFail<T>(_ throwingFunction: () throws -> T) -> MaybeWithSuccess<T> {
@@ -34,89 +41,8 @@ public func mightFail<T>(_ throwingFunction: () throws -> T) -> MaybeWithSuccess
3441
} catch {
3542
return maybe(error: error)
3643
}
37-
}
38-
39-
@inlinable
40-
public func mightFail<T>(_ throwingFunction: () throws -> T?) -> (error: Error?, result: T?, success: Bool) {
41-
do {
42-
let value = try throwingFunction()
43-
return (error: nil, result: value, success: true)
44-
} catch {
45-
return (error: error, result: nil, success: false)
46-
}
47-
}
48-
49-
/// Executes a throwing function and returns a tuple containing the error (if any) and the result (if successful).
50-
///
51-
/// This is a simplified version of the `mightFail` function that doesn't include the success boolean.
52-
///
53-
/// - Parameter throwingFunction: A function that might throw an error.
54-
/// - Returns: A tuple containing the error (if any) and the result (if successful).
55-
///
56-
/// Example usage:
57-
/// ```swift
58-
/// func divide(_ a: Int, by b: Int) throws -> Int {
59-
/// guard b != 0 else { throw DivisionError.divideByZero }
60-
/// return a / b
61-
/// }
62-
///
63-
/// let (error, result) = mightFail {
64-
/// try divide(10, by: 2)
65-
/// }
66-
///
67-
/// if let result = result {
68-
/// print("Division result: \(result)")
69-
/// } else {
70-
/// print("Division failed. Error: \(error)")
71-
/// }
72-
/// ```
73-
@inlinable
74-
public func mightFail<T>(_ throwingFunction: () throws -> T) -> Maybe<T> {
75-
let (error, result, _) = mightFail(throwingFunction)
76-
return (error, result)
77-
}
78-
79-
// MARK: - All Settled
80-
81-
/// Executes multiple throwing functions and returns an array of results.
82-
///
83-
/// This function allows you to execute multiple operations that might throw errors and collect all their results,
84-
/// regardless of whether they succeeded or failed.
85-
///
86-
/// - Parameter throwingFunctions: An array of functions that might throw errors.
87-
/// - Returns: An array of tuples, each containing the error (if any), the result (if successful), and a boolean indicating success for each function.
88-
///
89-
/// Example usage:
90-
/// ```swift
91-
/// func operation1() throws -> Int { return 1 }
92-
/// func operation2() throws -> Int { throw NSError(domain: "TestError", code: 1, userInfo: nil) }
93-
/// func operation3() throws -> Int { return 3 }
94-
///
95-
/// let results = mightFail([
96-
/// { try operation1() },
97-
/// { try operation2() },
98-
/// { try operation3() }
99-
/// ])
100-
///
101-
/// for (index, (error, result, success)) in results.enumerated() {
102-
/// if success {
103-
/// print("Operation \(index + 1) succeeded with result: \(result!)")
104-
/// } else {
105-
/// print("Operation \(index + 1) failed with error: \(error)")
106-
/// }
107-
/// }
108-
/// ```
109-
@inlinable
110-
public func mightFail<T>(_ throwingFunctions: [() throws -> T]) -> [MaybeWithSuccess<T>] {
111-
var results: [MaybeWithSuccess<T>] = []
112-
for throwingFunction in throwingFunctions {
113-
let (error, result, success) = mightFail(throwingFunction)
114-
results.append((error, result, success))
115-
}
116-
return results
117-
}
44+
}
11845

119-
// MARK: - Async
12046

12147
/// Executes an async throwing function and returns a tuple containing the error (if any), the result (if successful), and a boolean indicating success.
12248
///
@@ -141,11 +67,16 @@ public func mightFail<T>(_ throwingFunctions: [() throws -> T]) -> [MaybeWithSuc
14167
/// try await fetchUserData(id: 1)
14268
/// }
14369
///
144-
/// if success {
145-
/// print("User fetched successfully: \(user!)")
146-
/// } else {
70+
/// guard let user else {
14771
/// print("Failed to fetch user. Error: \(error)")
72+
/// return
14873
/// }
74+
/// // or
75+
/// guard success else {
76+
/// print("Failed to fetch user. Error: \(error)")
77+
/// return
78+
/// }
79+
/// print("User fetched successfully: \(user)")
14980
/// ```
15081
@available(iOS 13.0.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *)
15182
@inlinable
@@ -158,6 +89,9 @@ public func mightFail<T>(_ throwingFunction: @Sendable () async throws -> T) asy
15889
}
15990
}
16091

92+
93+
// MARK: Maybe without success
94+
16195
/// Executes an async throwing function and returns a tuple containing the error (if any) and the result (if successful).
16296
///
16397
/// This is a simplified version of the async `mightFail` function that doesn't include the success boolean.
@@ -180,11 +114,12 @@ public func mightFail<T>(_ throwingFunction: @Sendable () async throws -> T) asy
180114
/// try await processData()
181115
/// }
182116
///
183-
/// if let data = data {
184-
/// print("Data processed successfully: \(data)")
185-
/// } else {
117+
/// guard let data else {
186118
/// print("Data processing failed. Error: \(error)")
119+
/// return
187120
/// }
121+
///
122+
/// print("Data processed successfully: \(data)")
188123
/// ```
189124
@available(iOS 13.0.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *)
190125
@inlinable
@@ -193,88 +128,115 @@ public func mightFail<T>(_ throwingFunction: @Sendable () async throws -> T) asy
193128
return (error, result)
194129
}
195130

196-
// MARK: - Async All Settled
131+
/// Executes a throwing function and returns a tuple containing the error (if any) and the result (if successful).
132+
///
133+
/// This is a simplified version of the `mightFail` function that doesn't include the success boolean.
134+
///
135+
/// - Parameter throwingFunction: A function that might throw an error.
136+
/// - Returns: A tuple containing the error (if any) and the result (if successful).
137+
///
138+
/// Example usage:
139+
/// ```swift
140+
/// func divide(_ a: Int, by b: Int) throws -> Int {
141+
/// guard b != 0 else { throw DivisionError.divideByZero }
142+
/// return a / b
143+
/// }
144+
///
145+
/// let (error, result) = mightFail {
146+
/// try divide(10, by: 2)
147+
/// }
148+
///
149+
/// guard let result else {
150+
/// print("Division failed. Error: \(error)")
151+
/// return
152+
/// }
153+
///
154+
/// print("Division result: \(result)")
155+
/// ```
156+
@inlinable
157+
public func mightFail<T>(_ throwingFunction: () throws -> T) -> Maybe<T> {
158+
let (error, result, _) = mightFail(throwingFunction)
159+
return (error, result)
160+
}
161+
162+
// MARK: - All Settled
197163

198-
/// Executes multiple async throwing functions and returns an array of results.
164+
/// Executes multiple throwing functions and returns an array of results.
199165
///
200-
/// This function allows you to execute multiple asynchronous operations that might throw errors and collect all their results,
166+
/// This function allows you to execute multiple operations that might throw errors and collect all their results,
201167
/// regardless of whether they succeeded or failed.
202168
///
203-
/// - Parameter throwingFunctions: An array of async functions that might throw errors.
169+
/// - Parameter throwingFunctions: An array of functions that might throw errors.
204170
/// - Returns: An array of tuples, each containing the error (if any), the result (if successful), and a boolean indicating success for each function.
205171
///
206172
/// Example usage:
207173
/// ```swift
208-
/// func asyncOperation1() async throws -> Int { return 1 }
209-
/// func asyncOperation2() async throws -> Int { throw NSError(domain: "TestError", code: 2, userInfo: nil) }
210-
/// func asyncOperation3() async throws -> Int { return 3 }
174+
/// func operation1() throws -> Int { return 1 }
175+
/// func operation2() throws -> Int { throw NSError(domain: "TestError", code: 1, userInfo: nil) }
176+
/// func operation3() throws -> Int { return 3 }
211177
///
212-
/// let results = await mightFail([
213-
/// { try await asyncOperation1() },
214-
/// { try await asyncOperation2() },
215-
/// { try await asyncOperation3() }
178+
/// let results = mightFail([
179+
/// { try operation1() },
180+
/// { try operation2() },
181+
/// { try operation3() }
216182
/// ])
217183
///
218184
/// for (index, (error, result, success)) in results.enumerated() {
219-
/// if success {
220-
/// print("Async operation \(index + 1) succeeded with result: \(result!)")
221-
/// } else {
222-
/// print("Async operation \(index + 1) failed with error: \(error)")
185+
/// guard success else {
186+
/// print("Operation \(index + 1) failed with error: \(error)")
187+
/// continue
223188
/// }
189+
///
190+
/// print("Operation \(index + 1) succeeded with result: \(result!)")
224191
/// }
225192
/// ```
226-
@available(iOS 13.0.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *)
227193
@inlinable
228-
public func mightFail<T>(_ throwingFunctions: [@Sendable () async throws -> T]) async -> [MaybeWithSuccess<T>] {
194+
public func mightFail<T>(_ throwingFunctions: [() throws -> T]) -> [MaybeWithSuccess<T>] {
229195
var results: [MaybeWithSuccess<T>] = []
230196
for throwingFunction in throwingFunctions {
231-
let (error, result, success) = await mightFail(throwingFunction)
197+
let (error, result, success) = mightFail(throwingFunction)
232198
results.append((error, result, success))
233199
}
234200
return results
235201
}
236202

237-
/// Executes an async throwing function that returns an optional value and returns a tuple containing the error (if any),
238-
/// the result (if successful), and a boolean indicating success.
203+
204+
/// Executes multiple async throwing functions and returns an array of results.
239205
///
240-
/// This function is the asynchronous version of `mightFail` for optional return types, allowing you to handle
241-
/// potentially throwing async operations that may return nil.
206+
/// This function allows you to execute multiple asynchronous operations that might throw errors and collect all their results,
207+
/// regardless of whether they succeeded or failed.
242208
///
243-
/// - Parameter throwingFunction: An async function that might throw an error and returns an optional value.
244-
/// - Returns: A tuple containing the error (if any), the result (if successful), and a boolean indicating success.
209+
/// - Parameter throwingFunctions: An array of async functions that might throw errors.
210+
/// - Returns: An array of tuples, each containing the error (if any), the result (if successful), and a boolean indicating success for each function.
245211
///
246-
/// Example:
212+
/// Example usage:
247213
/// ```swift
248-
/// func fetchUserProfile(id: Int) async throws -> UserProfile? {
249-
/// try await Task.sleep(nanoseconds: 1_000_000_000) // Sleep for 1 second
250-
/// if id < 0 {
251-
/// throw FetchError.invalidId
252-
/// }
253-
/// return id == 0 ? nil : UserProfile(id: id, name: "User \(id)")
254-
/// }
214+
/// func asyncOperation1() async throws -> Int { return 1 }
215+
/// func asyncOperation2() async throws -> Int { throw NSError(domain: "TestError", code: 2, userInfo: nil) }
216+
/// func asyncOperation3() async throws -> Int { return 3 }
255217
///
256-
/// let (error, profile, success) = await mightFail {
257-
/// try await fetchUserProfile(id: 1)
258-
/// }
218+
/// let results = await mightFail([
219+
/// { try await asyncOperation1() },
220+
/// { try await asyncOperation2() },
221+
/// { try await asyncOperation3() }
222+
/// ])
259223
///
260-
/// if success {
261-
/// if let profile = profile {
262-
/// print("Profile fetched successfully: \(profile)")
263-
/// } else {
264-
/// print("No profile found")
224+
/// for (index, (error, result, success)) in results.enumerated() {
225+
/// guard success else {
226+
/// print("Async operation \(index + 1) failed with error: \(error)")
227+
/// continue
265228
/// }
266-
/// } else {
267-
/// print("Failed to fetch profile. Error: \(error)")
268-
/// }
229+
///
230+
/// print("Async operation \(index + 1) succeeded with result: \(result!)")
269231
/// }
270232
/// ```
271233
@available(iOS 13.0.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *)
272234
@inlinable
273-
public func mightFail<T>(_ throwingFunction: @Sendable () async throws -> T?) async -> (error: Error?, result: T?, success: Bool) {
274-
do {
275-
let value = try await throwingFunction()
276-
return (error: nil, result: value, success: true)
277-
} catch {
278-
return (error: error, result: nil, success: false)
235+
public func mightFail<T>(_ throwingFunctions: [@Sendable () async throws -> T]) async -> [MaybeWithSuccess<T>] {
236+
var results: [MaybeWithSuccess<T>] = []
237+
for throwingFunction in throwingFunctions {
238+
let (error, result, success) = await mightFail(throwingFunction)
239+
results.append((error, result, success))
279240
}
280-
}
241+
return results
242+
}

0 commit comments

Comments
 (0)