Skip to content

Instantly share code, notes, and snippets.

@ilyannn
Last active August 29, 2015 14:03
Show Gist options
  • Save ilyannn/6375679ef5102158b1eb to your computer and use it in GitHub Desktop.
Save ilyannn/6375679ef5102158b1eb to your computer and use it in GitHub Desktop.
How to encapsulate NSError** in Swift
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")
@ilyannn
Copy link
Author

ilyannn commented Jul 14, 2014

Note: doesn't really work in my playground; mostly just an example of a possible syntax.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment