RotateController.swift 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //
  2. // RotateController.swift
  3. // Todos
  4. //
  5. // Created by Sam Jaffe on 3/13/26.
  6. //
  7. import Foundation
  8. final class RotateController {
  9. static func ymd(_ date: Date) -> String { RotateController().ymd(date) }
  10. func ymd(_ date: Date) -> String {
  11. date.formatted(.iso8601.year().month().day())
  12. }
  13. func saveAndRotate(_ items: [Project], _ date: inout Date,
  14. _ tracking: inout RotateTracking) {
  15. SaveController().save(items, onDate: ymd(date))
  16. tracking.summary = summarize(items)
  17. rotate(items, &tracking)
  18. date = Date()
  19. }
  20. func summarize(_ items: [Project]) -> String? {
  21. var summary = ""
  22. for item in items {
  23. item.tasks.filter(isComplete).map(\.name).forEach { name in
  24. summary += "- \(item.name) > \(name)\n"
  25. }
  26. for task in item.tasks {
  27. task.subtasks.filter(isComplete).map(\.name).forEach { name in
  28. summary += "- \(item.name) > \(task.name) > \(name)\n"
  29. }
  30. }
  31. }
  32. return summary.isEmpty ? nil : summary
  33. }
  34. private func rotate(_ items: [Project], _ tracking: inout RotateTracking) {
  35. for item in items {
  36. cleanStatuses(&item.tasks)
  37. for task in item.tasks {
  38. cleanStatuses(&task.subtasks)
  39. }
  40. }
  41. }
  42. private func isComplete<T: Filterable>(_ arg: T) -> Bool {
  43. arg.status == .complete
  44. }
  45. private func cleanStatuses<T: Filterable>(_ items: inout [T]) {
  46. items.removeAll(where: isComplete)
  47. for var item in items where item.status == .inProgress {
  48. item.status = .todo
  49. }
  50. }
  51. }