Skip to content

Instantly share code, notes, and snippets.

@drumnkyle
Created November 30, 2016 04:16
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save drumnkyle/9d1b0d84b0345881b2a44d2a0d26bafc to your computer and use it in GitHub Desktop.
Makes it so you can throw an error and revert any mutation changes in a struct
protocol SafeMutation {
mutating func safeMutate(_ work: () throws -> ()) rethrows
}
extension SafeMutation {
mutating func safeMutate(_ work: () throws -> ()) rethrows {
let old = self
do {
try work()
} catch {
self = old
throw error
}
}
}
// Example usage
struct Note: SafeMutation {
var accidental: Accidental
mutating func changeAccidental(_ number: Int) throws {
accidental = accidental == .sharp ? .flat : .sharp
if number == 1 { throw NoteError.bad }
}
mutating func safeChangeAccidental(_ number: Int) throws {
try safeMutate {
accidental = accidental == .sharp ? .flat : .sharp
if number == 1 { throw NoteError.bad }
}
}
}
var noteStruct = Note(accidental: .sharp)
print(noteStruct.accidental) // .sharp
// Unsafe version
do {
try noteStruct.changeAccidental(1)
} catch {
print(noteStruct.accidental) // .flat
}
print(noteStruct.accidental) // .flat
// Safe version
do {
try noteStruct.safeChangeAccidental(1) // Already flat
} catch {
print(noteStruct.accidental) // .flat
}
print(noteStruct.accidental) // .flat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment