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.
		
		
		
		
		
			
		
			
				
	
	
		
			114 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			114 lines
		
	
	
		
			3.2 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
 | |
|     }
 | |
| }
 | |
| 
 | |
| // 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)
 | |
|     }
 | |
| }
 |