Skip to content

Instantly share code, notes, and snippets.

@vikingosegundo
Last active November 16, 2022 12:38
Show Gist options
  • Save vikingosegundo/74f6cdbaf9409fa6d3b6387547064592 to your computer and use it in GitHub Desktop.
Save vikingosegundo/74f6cdbaf9409fa6d3b6387547064592 to your computer and use it in GitHub Desktop.
struct TodoItem:Identifiable {
enum Change {
case title (to:String)
case due (to:TodoDate)
case location(to:Location)
case finish
case unfinish
}
// members
let id : UUID
let title : String
let completed: Bool
let created : Date
let due : TodoDate
let location : Location
// initialisers
init(title:String) { self.init(UUID(),title,false,.unknown, Date(),.unknown) }
private
init(_ i:UUID,_ t:String,_ c:Bool,_ d:TodoDate,_ cd:Date,_ l:Location) { id=i; title=t; completed=c; due=d; created=cd; location=l }
func alter(_ c:Change...) -> Self { c.reduce(self) { $0.alter($1) } }
private
func alter(_ c:Change ) -> Self {
switch c {
case let .title(to:t): return Self(id,t ,completed,due,created,location)
case .finish : return Self(id,title,true ,due,created,location)
case .unfinish : return Self(id,title,false ,due,created,location)
case let .location(to:l): return Self(id,title,false ,due,created,l )
case let .due(to:.timeSpan(.start(.from(b),.to(e)))):
return e > b //check for timespans if dates are in correct order
? Self(id,title,completed,.timeSpan(.start(.from(b),.to(e))),created,location)
: self
case let .due(to:d): return Self(id,title,completed,d ,created,location)
}
}
}
struct TodoList: Identifiable {
enum Change {
case add (Add ); public enum Add { case item(TodoItem) }
case remove(Remove); public enum Remove { case item(TodoItem) }
case update(Update); public enum Update { case item(TodoItem) }
}
// members
let id : UUID
let items: [TodoItem]
// initializers
init() { self.init(UUID(),[]) }
private
init(_ i:UUID,_ its:[TodoItem]) { id = i; items = its }
func alter(_ c:Change...) -> Self { c.reduce(self) { $0.alter($1) } }
private
func alter(_ c:Change ) -> Self {
switch c {
case let .add (.item(i)): return Self(id,items + [i])
case let .remove(.item(i)): return Self(id,items - [i])
case let .update(.item(i)): return
items.contains(where:{ $0.id == i.id })
? self
.alter(
.remove(.item(i)),
.add (.item(i)))
: self
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment