| enum State { | |
| case Success(value:String) | |
| case Error(error:NSError) | |
| } | |
| class Bound:Printable { | |
| let pointer:NSErrorPointer | |
| var state:State | |
| var step:Int = 0 | |
| init(initial:String, pointer:NSErrorPointer) { | |
| self.pointer = pointer | |
| self.state = .Success(value: initial) | |
| } | |
| var description:String { | |
| var stateDescription:String! | |
| switch state { | |
| case .Error(let error): stateDescription = "Error(\(error))" | |
| case .Success(let value): stateDescription = "Success(\(value))" | |
| } | |
| return "Step \(step++): " + stateDescription | |
| } | |
| func swiftStyle(op:(String) -> State) -> Bound { | |
| println(self) | |
| switch state { | |
| case .Success(let value): | |
| state = op(value) | |
| default: break; | |
| } | |
| switch state { | |
| case .Error(let error): | |
| if pointer { | |
| pointer.memory = error // wrapped if you like | |
| } | |
| default: break | |
| } | |
| return self | |
| } | |
| func objCStyle(op2:(String, NSErrorPointer) -> String?) -> Bound { | |
| swiftStyle { (incoming:String) in | |
| let localPointer = UnsafePointer<NSError>.alloc(1) | |
| if let newValue = op2(incoming, NSErrorPointer(localPointer)) { | |
| return State.Success(value: newValue) | |
| } | |
| var localError = localPointer.move() | |
| return State.Error (error: localError) | |
| } | |
| return self | |
| } | |
| func cantFail(op:(inout x:String) -> ()) -> Bound { | |
| swiftStyle { (x:String) in | |
| var y:String = x | |
| op(x: &y) | |
| return State.Success(value: y) | |
| } | |
| return self | |
| } | |
| func debugErrors(op:(NSError) -> ()) -> Bound { | |
| switch state { | |
| case .Error(let error): op(error) | |
| default: break | |
| } | |
| return self | |
| } | |
| func value() -> String? { | |
| switch state { | |
| case .Success(let value): return value | |
| default: return nil | |
| } | |
| } | |
| } | |
| class SomeError:NSError { } | |
| func load(website:String, errorPointer:NSErrorPointer = nil) -> String? | |
| { return Bound(initial:website, pointer: errorPointer) | |
| .swiftStyle { | |
| $0.isEmpty ? .Error(error:SomeError()) | |
| : .Success(value: "http://www." + $0 + ".com") | |
| } | |
| .objCStyle { (incoming, pointer) in | |
| let url = NSURL(string: incoming) | |
| return NSString(contentsOfURL:url, encoding:NSUTF8StringEncoding, error:pointer) | |
| } | |
| .debugErrors { (error:NSError) in | |
| println(error) // or set breakpoint here | |
| } | |
| .cantFail { (inout value:String) in | |
| value += "" | |
| } | |
| .value() | |
| } | |
| load("google") | |
Note: doesn't really work in my playground; mostly just an example of a possible syntax.