RotateController.swift 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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 {
  48. if item.status == .inProgress {
  49. item.status = .todo
  50. }
  51. }
  52. }
  53. }