SweeterSwift/Source/Swift+Sweeter.swift

102 lines
3.2 KiB
Swift

//
// Swift+Sweeter.swift
//
// Created by Yonat Sharon on 2019-02-21.
//
public extension CaseIterable where Self: Equatable {
/// Sweeter: Index of current case in `allCases`.
var index: Int {
let all = Array(Self.allCases)
return all.firstIndex(of: self)! // swiftlint:disable:this force_unwrapping
}
}
// from https://gist.github.com/siejkowski/a2b187800f2e28b53c96
public extension Sequence where Element: Optionable {
/// Sweeter: Shorthand for `compactMap { $0 }`.
var compact: [Element.Wrapped] {
return compactMap { $0.value }
}
}
public protocol Optionable {
associatedtype Wrapped
var value: Wrapped? { get }
}
// extension for Optional provides the implementations for Optional enum
extension Optional: Optionable {
public var value: Wrapped? { return self }
}
infix operator =?: AssignmentPrecedence
/// Sweeter: Assign iff right side is not nil.
public func =? <T>(lhs: inout T, rhs: T?) {
if nil != rhs, let rhs = rhs {
lhs = rhs
}
}
public protocol DefaultConstructible {
init()
}
extension Optional: DefaultConstructible {
public init() {
self = .none
}
}
extension IntegerLiteralType: DefaultConstructible {}
extension BooleanLiteralType: DefaultConstructible {}
extension FloatLiteralType: DefaultConstructible {}
extension StringLiteralType: DefaultConstructible {}
extension Array: DefaultConstructible {}
extension Dictionary: DefaultConstructible {}
extension Set: DefaultConstructible {}
// based on https://sveinhal.github.io/2016/03/16/retain-cycles-function-references/
/// Sweeter: Pass a member function as an @escaping closure without retaining its object.
///
/// Example: `var closure = weak(self, in: MyClass.someFunction)`
public func weak<T: AnyObject>(_ instance: T, in classFunction: @escaping (T) -> () -> Void) -> () -> Void {
return { [weak instance] in
guard let instance = instance else { return }
classFunction(instance)()
}
}
/// Sweeter: Pass a member function as an @escaping closure without retaining its object.
///
/// Example: `var closure = weak(self, in: MyClass.someFunction)`
public func weak<T: AnyObject, U>(_ instance: T, in classFunction: @escaping (T) -> (U) -> Void) -> (U) -> Void {
return { [weak instance] arguments in
guard let instance = instance else { return }
classFunction(instance)(arguments)
}
}
/// Sweeter: Pass a member function as an @escaping closure without retaining its object.
///
/// Example: `var closure = weak(self, in: MyClass.someFunction)`
public func weak<T: AnyObject, V: DefaultConstructible>(_ instance: T, in classFunction: @escaping (T) -> () -> V) -> () -> V {
return { [weak instance] in
guard let instance = instance else { return V() }
return classFunction(instance)()
}
}
/// Sweeter: Pass a member function as an @escaping closure without retaining its object.
///
/// Example: `var closure = weak(self, in: MyClass.someFunction)`
public func weak<T: AnyObject, U, V: DefaultConstructible>(_ instance: T, in classFunction: @escaping (T) -> (U) -> V) -> (U) -> V {
return { [weak instance] arguments in
guard let instance = instance else { return V() }
return classFunction(instance)(arguments)
}
}