2025-03-23 00:27:49 -03:00
|
|
|
//
|
|
|
|
|
// Copyright (c) 2020 Loverde Co.
|
|
|
|
|
//
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
|
//
|
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
|
//
|
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
// THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
2026-02-06 12:25:34 -03:00
|
|
|
#if canImport(UIKit)
|
2025-03-23 00:27:49 -03:00
|
|
|
import UIKit
|
2026-02-06 12:25:34 -03:00
|
|
|
#endif
|
2025-03-23 00:27:49 -03:00
|
|
|
|
|
|
|
|
public extension Optional {
|
|
|
|
|
/// Get self of default value (if self is nil).
|
|
|
|
|
///
|
|
|
|
|
/// let foo: String? = nil
|
|
|
|
|
/// print(foo.unwrapped(or: "bar")) -> "bar"
|
|
|
|
|
///
|
|
|
|
|
/// let bar: String? = "bar"
|
|
|
|
|
/// print(bar.unwrapped(or: "foo")) -> "bar"
|
|
|
|
|
///
|
|
|
|
|
/// - Parameter defaultValue: default value to return if self is nil.
|
|
|
|
|
/// - Returns: self if not nil or default value if nil.
|
|
|
|
|
func unwrapped(or defaultValue: Wrapped) -> Wrapped {
|
|
|
|
|
// http://www.russbishop.net/improving-optionals
|
|
|
|
|
return self ?? defaultValue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Gets the wrapped value of an optional. If the optional is `nil`, throw a custom error.
|
|
|
|
|
///
|
|
|
|
|
/// let foo: String? = nil
|
|
|
|
|
/// try print(foo.unwrapped(or: MyError.notFound)) -> error: MyError.notFound
|
|
|
|
|
///
|
|
|
|
|
/// let bar: String? = "bar"
|
|
|
|
|
/// try print(bar.unwrapped(or: MyError.notFound)) -> "bar"
|
|
|
|
|
///
|
|
|
|
|
/// - Parameter error: The error to throw if the optional is `nil`.
|
|
|
|
|
/// - Returns: The value wrapped by the optional.
|
|
|
|
|
/// - Throws: The error passed in.
|
|
|
|
|
func unwrapped(or error: Error) throws -> Wrapped {
|
|
|
|
|
guard let wrapped = self else { throw error }
|
|
|
|
|
return wrapped
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Runs a block to Wrapped if not nil
|
|
|
|
|
///
|
|
|
|
|
/// let foo: String? = nil
|
|
|
|
|
/// foo.run { unwrappedFoo in
|
|
|
|
|
/// // block will never run sice foo is nill
|
|
|
|
|
/// print(unwrappedFoo)
|
|
|
|
|
/// }
|
|
|
|
|
///
|
|
|
|
|
/// let bar: String? = "bar"
|
|
|
|
|
/// bar.run { unwrappedBar in
|
|
|
|
|
/// // block will run sice bar is not nill
|
|
|
|
|
/// print(unwrappedBar) -> "bar"
|
|
|
|
|
/// }
|
|
|
|
|
///
|
|
|
|
|
/// - Parameter block: a block to run if self is not nil.
|
|
|
|
|
func run(_ block: (Wrapped) -> Void) {
|
|
|
|
|
// http://www.russbishop.net/improving-optionals
|
|
|
|
|
_ = map(block)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Assign an optional value to a variable only if the value is not nil.
|
|
|
|
|
///
|
|
|
|
|
/// let someParameter: String? = nil
|
|
|
|
|
/// let parameters = [String: Any]() // Some parameters to be attached to a GET request
|
|
|
|
|
/// parameters[someKey] ??= someParameter // It won't be added to the parameters dict
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - lhs: Any?
|
|
|
|
|
/// - rhs: Any?
|
|
|
|
|
static func ??= (lhs: inout Optional, rhs: Optional) {
|
|
|
|
|
guard let rhs = rhs else { return }
|
|
|
|
|
lhs = rhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Assign an optional value to a variable only if the variable is nil.
|
|
|
|
|
///
|
|
|
|
|
/// var someText: String? = nil
|
|
|
|
|
/// let newText = "Foo"
|
|
|
|
|
/// let defaultText = "Bar"
|
|
|
|
|
/// someText ?= newText // someText is now "Foo" because it was nil before
|
|
|
|
|
/// someText ?= defaultText // someText doesn't change its value because it's not nil
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - lhs: Any?
|
|
|
|
|
/// - rhs: Any?
|
|
|
|
|
static func ?= (lhs: inout Optional, rhs: @autoclosure () -> Optional) {
|
|
|
|
|
if lhs == nil {
|
|
|
|
|
lhs = rhs()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: - Methods (Collection)
|
|
|
|
|
|
|
|
|
|
public extension Optional where Wrapped: Collection {
|
|
|
|
|
/// Check if optional is nil or empty collection.
|
|
|
|
|
var isNilOrEmpty: Bool {
|
|
|
|
|
return self?.isEmpty ?? true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns the collection only if it is not nil and not empty.
|
|
|
|
|
var nonEmpty: Wrapped? {
|
|
|
|
|
return (self?.isEmpty ?? true) ? nil : self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: - Methods (RawRepresentable, RawValue: Equatable)
|
|
|
|
|
|
|
|
|
|
public extension Optional where Wrapped: RawRepresentable, Wrapped.RawValue: Equatable {
|
|
|
|
|
// swiftlint:disable missing_swifterswift_prefix
|
|
|
|
|
|
|
|
|
|
/// Returns a Boolean value indicating whether two values are equal.
|
|
|
|
|
///
|
|
|
|
|
/// Equality is the inverse of inequality. For any values `a` and `b`,
|
|
|
|
|
/// `a == b` implies that `a != b` is `false`.
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - lhs: A value to compare.
|
|
|
|
|
/// - rhs: Another value to compare.
|
|
|
|
|
@inlinable static func == (lhs: Optional, rhs: Wrapped.RawValue?) -> Bool {
|
|
|
|
|
return lhs?.rawValue == rhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns a Boolean value indicating whether two values are equal.
|
|
|
|
|
///
|
|
|
|
|
/// Equality is the inverse of inequality. For any values `a` and `b`,
|
|
|
|
|
/// `a == b` implies that `a != b` is `false`.
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - lhs: A value to compare.
|
|
|
|
|
/// - rhs: Another value to compare.
|
|
|
|
|
@inlinable static func == (lhs: Wrapped.RawValue?, rhs: Optional) -> Bool {
|
|
|
|
|
return lhs == rhs?.rawValue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns a Boolean value indicating whether two values are not equal.
|
|
|
|
|
///
|
|
|
|
|
/// Inequality is the inverse of equality. For any values `a` and `b`,
|
|
|
|
|
/// `a != b` implies that `a == b` is `false`.
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - lhs: A value to compare.
|
|
|
|
|
/// - rhs: Another value to compare.
|
|
|
|
|
@inlinable static func != (lhs: Optional, rhs: Wrapped.RawValue?) -> Bool {
|
|
|
|
|
return lhs?.rawValue != rhs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns a Boolean value indicating whether two values are not equal.
|
|
|
|
|
///
|
|
|
|
|
/// Inequality is the inverse of equality. For any values `a` and `b`,
|
|
|
|
|
/// `a != b` implies that `a == b` is `false`.
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - lhs: A value to compare.
|
|
|
|
|
/// - rhs: Another value to compare.
|
|
|
|
|
@inlinable static func != (lhs: Wrapped.RawValue?, rhs: Optional) -> Bool {
|
|
|
|
|
return lhs != rhs?.rawValue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// swiftlint:enable missing_swifterswift_prefix
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: - Operators
|
|
|
|
|
|
|
|
|
|
infix operator ??=: AssignmentPrecedence
|
|
|
|
|
infix operator ?=: AssignmentPrecedence
|