import Foundation /// Completion state of a workout or an individual exercise log. Persisted as its /// raw string in both the JSON documents and the SwiftData cache. enum WorkoutStatus: String, CaseIterable, Codable, Sendable { case notStarted case inProgress case completed case skipped var displayName: String { switch self { case .notStarted: "Not Started" case .inProgress: "In Progress" case .completed: "Completed" case .skipped: "Skipped" } } var name: String { displayName } } /// How an exercise's effort is measured. Persisted as its raw `Int` value. enum LoadType: Int, CaseIterable, Codable, Sendable { case none = 0 case weight = 1 case duration = 2 var name: String { switch self { case .none: "None" case .weight: "Weight" case .duration: "Duration" } } } /// The kind of training a split represents — used to tag the watch's Apple Health /// workout so it lands in the right category (and credits the rings correctly). /// Persisted as its raw `Int` on `SplitDocument`; the `HKWorkoutActivityType` /// mapping lives in `Shared/HealthKit/HealthKitMapping.swift` to keep this enum /// HealthKit-free. enum WorkoutActivityType: Int, CaseIterable, Codable, Sendable { case traditionalStrength = 0 // default case functionalStrength = 1 case hiit = 2 case coreTraining = 3 case cardio = 4 case cycling = 5 var displayName: String { switch self { case .traditionalStrength: "Strength Training" case .functionalStrength: "Functional Strength" case .hiit: "HIIT" case .coreTraining: "Core Training" case .cardio: "Cardio" case .cycling: "Cycling" } } var systemImage: String { switch self { case .traditionalStrength: "dumbbell.fill" case .functionalStrength: "figure.strengthtraining.functional" case .hiit: "figure.highintensity.intervaltraining" case .coreTraining: "figure.core.training" case .cardio: "figure.run" case .cycling: "figure.outdoor.cycle" } } } /// Where a workout's health metrics came from: real watch sensors, or — for records /// written by app versions up to 2.x — a phone-side MET estimate made when no watch /// session ran. The phone no longer writes estimates (recording is watch-only), but /// `phoneEstimate` is retained so legacy documents on disk still decode. Persisted in /// `WorkoutMetrics`. enum MetricSource: String, Codable, Sendable { case watch case phoneEstimate } /// Display unit for weights. The stored weight values are plain integers and are /// never rewritten when this changes — switching only relabels what's shown. enum WeightUnit: String, CaseIterable, Codable, Sendable { case lb case kg var displayName: String { switch self { case .lb: "Pounds (lb)" case .kg: "Kilograms (kg)" } } var abbreviation: String { switch self { case .lb: "lb" case .kg: "kg" } } /// Render a stored weight value with the current unit's label, e.g. "135 lb". func format(_ value: Int) -> String { "\(value) \(abbreviation)" } }