// // GroceryStateModels.swift // Nextcloud Cookbook iOS Client // import Foundation /// Tracks grocery list state for a recipe, stored as `_groceryState` in the recipe JSON on the server. struct GroceryState: Codable { var version: Int = 1 var lastModified: String var items: [String: GroceryItemState] init(lastModified: String = GroceryStateDate.now(), items: [String: GroceryItemState] = [:]) { self.version = 1 self.lastModified = lastModified self.items = items } } struct GroceryItemState: Codable { enum Status: String, Codable { case added case completed case removed } var status: Status var addedAt: String var modifiedAt: String init(status: Status, addedAt: String = GroceryStateDate.now(), modifiedAt: String = GroceryStateDate.now()) { self.status = status self.addedAt = addedAt self.modifiedAt = modifiedAt } } /// ISO 8601 date helpers. Dates are stored as strings to avoid coupling to a parent encoder's date strategy. enum GroceryStateDate { private static let formatter: ISO8601DateFormatter = { let f = ISO8601DateFormatter() f.formatOptions = [.withInternetDateTime] return f }() static func now() -> String { formatter.string(from: Date()) } static func date(from string: String) -> Date? { formatter.date(from: string) } static func string(from date: Date) -> String { formatter.string(from: date) } }