mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Swift
		
	
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
 | 
						|
 | 
						|
import Foundation
 | 
						|
 | 
						|
public enum Updatable<Wrapped>: ExpressibleByNilLiteral {
 | 
						|
    /// A cleared value.
 | 
						|
    ///
 | 
						|
    /// In code, the cleared of a value is typically written using the `nil`
 | 
						|
    /// literal rather than the explicit `.remove` enumeration case.
 | 
						|
    case remove
 | 
						|
    
 | 
						|
    /// The existing value, this will leave whatever value is currently available.
 | 
						|
    case existing
 | 
						|
 | 
						|
    /// An updated value, stored as `Wrapped`.
 | 
						|
    case update(Wrapped)
 | 
						|
    
 | 
						|
    // MARK: - ExpressibleByNilLiteral
 | 
						|
    
 | 
						|
    public init(nilLiteral: ()) {
 | 
						|
        self = .remove
 | 
						|
    }
 | 
						|
    
 | 
						|
    public static func updateIf(_ maybeValue: Wrapped?) -> Updatable<Wrapped> {
 | 
						|
        switch maybeValue {
 | 
						|
            case .some(let value): return .update(value)
 | 
						|
            default: return .existing
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    public static func updateTo(_ maybeValue: Wrapped?) -> Updatable<Wrapped> {
 | 
						|
        switch maybeValue {
 | 
						|
            case .some(let value): return .update(value)
 | 
						|
            default: return .remove
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    // MARK: - Functions
 | 
						|
    
 | 
						|
    public func value(existing: Wrapped) -> Wrapped? {
 | 
						|
        switch self {
 | 
						|
            case .remove: return nil
 | 
						|
            case .existing: return existing
 | 
						|
            case .update(let newValue): return newValue
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    public func value(existing: Wrapped) -> Wrapped {
 | 
						|
        switch self {
 | 
						|
            case .remove: fatalError("Attempted to assign a 'removed' value to a non-null")
 | 
						|
            case .existing: return existing
 | 
						|
            case .update(let newValue): return newValue
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// MARK: - Coalesing-nil operator
 | 
						|
 | 
						|
public func ?? <T>(updatable: Updatable<T>, existingValue: @autoclosure () throws -> T) rethrows -> T {
 | 
						|
    switch updatable {
 | 
						|
        case .remove: fatalError("Attempted to assign a 'removed' value to a non-null")
 | 
						|
        case .existing: return try existingValue()
 | 
						|
        case .update(let newValue): return newValue
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
public func ?? <T>(updatable: Updatable<T>, existingValue: @autoclosure () throws -> T?) rethrows -> T? {
 | 
						|
    switch updatable {
 | 
						|
        case .remove: return nil
 | 
						|
        case .existing: return try existingValue()
 | 
						|
        case .update(let newValue): return newValue
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
public func ?? <T>(updatable: Updatable<Optional<T>>, existingValue: @autoclosure () throws -> T?) rethrows -> T? {
 | 
						|
    switch updatable {
 | 
						|
        case .remove: return nil
 | 
						|
        case .existing: return try existingValue()
 | 
						|
        case .update(let newValue): return newValue
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// MARK: - ExpressibleBy Conformance
 | 
						|
 | 
						|
extension Updatable {
 | 
						|
    public init(_ value: Wrapped) {
 | 
						|
        self = .update(value)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
extension Updatable: ExpressibleByUnicodeScalarLiteral, ExpressibleByExtendedGraphemeClusterLiteral, ExpressibleByStringLiteral where Wrapped == String {
 | 
						|
    public init(stringLiteral value: Wrapped) {
 | 
						|
        self = .update(value)
 | 
						|
    }
 | 
						|
    
 | 
						|
    public init(extendedGraphemeClusterLiteral value: Wrapped) {
 | 
						|
        self = .update(value)
 | 
						|
    }
 | 
						|
    
 | 
						|
    public init(unicodeScalarLiteral value: Wrapped) {
 | 
						|
        self = .update(value)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
extension Updatable: ExpressibleByIntegerLiteral where Wrapped == Int {
 | 
						|
    public init(integerLiteral value: Int) {
 | 
						|
        self = .update(value)
 | 
						|
      }
 | 
						|
}
 | 
						|
 | 
						|
extension Updatable: ExpressibleByFloatLiteral where Wrapped == Double {
 | 
						|
    public init(floatLiteral value: Double) {
 | 
						|
        self = .update(value)
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
extension Updatable: ExpressibleByBooleanLiteral where Wrapped == Bool {
 | 
						|
    public init(booleanLiteral value: Bool) {
 | 
						|
        self = .update(value)
 | 
						|
    }
 | 
						|
}
 |