Skip to content

Instantly share code, notes, and snippets.

@vikingosegundo
Created May 14, 2021 19:21
Show Gist options
  • Save vikingosegundo/273cc892d1ff445b37a929b3c0aed732 to your computer and use it in GitHub Desktop.
Save vikingosegundo/273cc892d1ff445b37a929b3c0aed732 to your computer and use it in GitHub Desktop.
public
struct TodoItem: Identifiable, Hashable, Codable {
public enum Change: Equatable, Identifiable {
public var id: String {
switch self {
case .by(.updating(.completed(let b))): return "\(b)"
case .by(.updating(.dueDate (let d))): return d != nil ? "\(d!)" : "\(Date())"
case .by(.updating(.text (let t))): return t
case .by(.updating(.fork (let inner))): return inner.reduce("") { "\($0)\($1)" }
}
}
case by(_By)
public enum _By: Equatable {
case updating(_Changing)
public enum _Changing: Equatable {
case text (to: String)
case completed(to: Bool )
case dueDate (to: Date? )
case fork ( [Change])
}
}
}
public let text : String
public let completed : Bool
public let id : UUID
public let dueDate : Date?
public let alterDate : Date?
public let creationDate: Date
public init(text: String) { self.init(UUID(), text, false, nil, Date(), nil) }
fileprivate func alter(_ changes: [Change] ) -> TodoItem { changes.reduce(self) { $0.alter($1) } }
}
private
extension TodoItem{
private init (_ id: UUID, _ text: String, _ completed: Bool, _ dueDate: Date?, _ creationDate: Date, _ alterDate: Date?) {
self.text = text
self.completed = completed
self.id = id
self.creationDate = creationDate
self.dueDate = dueDate
self.alterDate = alterDate
}
private func alter(_ change: Change) -> TodoItem {
let changedItem = item(with: change)
switch change {
case .by(.updating(.fork(_))):
return changedItem
default:
return bruttoEqual(lhs: changedItem, rhs: self) ? self : changedItem
}
}
private func item(with change: Change) -> TodoItem {
let altered = Date()
switch change {
case .by(.updating(.text (let text ))): return TodoItem(id , text, completed, dueDate, creationDate, altered )
case .by(.updating(.completed(let completed))): return TodoItem(id , text, completed, dueDate, creationDate, altered )
case .by(.updating(.dueDate (let dueDate ))): return TodoItem(id , text, completed, dueDate, creationDate, altered )
case .by(.updating(.fork (let changes ))): return TodoItem(UUID(), text, completed, dueDate, creationDate, alterDate).alter(changes)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment