refactor Remove workout identifiers

Keep workout prescriptions free of persistence identity. Routines now use\ntheir stored workout values for traversal, and the Ideal Routine remains\nprivate to the core implementation.

Commit
b6263f09448c7aaacb5f275fc2531e930aed261a
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/core/prescription.ml
index f8bca3c4..fe15e744 100644..100644
@@ -92,21 +92,18 @@
92 92 end
93 93
94 94 module Workout = struct
95 Removed: type id = string
96 95 type error = Empty_workout
97 Removed: type t = { id : id; name : string; stimuli : Stimulus.t list }
96 Added: type t = { name : string; stimuli : Stimulus.t list }
98 97
99 98 exception Invalid of error
100 99
101 Removed: let make ~id ~name ~stimuli =
100 Added: let make ~name ~stimuli =
102 101 match stimuli with
103 102 | [] -> raise (Invalid Empty_workout)
104 Removed: | _ -> { id; name; stimuli }
103 Added: | _ -> { name; stimuli }
105 104
106 Removed: let id t = t.id
107 105 let name t = t.name
108 106 let stimuli t = t.stimuli
109 Removed: let equal a b = String.equal a.id b.id
110 107 let pp ppf t = Format.pp_print_string ppf t.name
111 108 end
112 109
@@ -129,7 +126,7 @@
129 126 let rec next = function
130 127 | [] | [ _ ] -> List.hd t.workouts
131 128 | w :: (following :: _ as rest) ->
132 Removed: if Workout.equal w performed then following else next rest
129 Added: if w == performed then following else next rest
133 130 in
134 131 next t.workouts
135 132
@@ -138,7 +135,7 @@
138 135
139 136 let recovery_after t performed =
140 137 match List.rev t.workouts with
141 Removed: | last :: _ when Workout.equal last performed -> cycle_rest
138 Added: | last :: _ when last == performed -> cycle_rest
142 139 | _ -> training_interval
143 140
144 141 (* {1 The Ideal Routine} *)
@@ -169,10 +166,10 @@
169 166 (Stimulus.Pre_exhaust
170 167 { isolation = movement isolation; compound = movement compound })
171 168
172 Removed: let day ~id ~name stimuli = Workout.make ~id ~name ~stimuli
169 Added: let day ~name stimuli = Workout.make ~name ~stimuli
173 170
174 171 let ideal_day_one =
175 Removed: day ~id:"ideal-day-1" ~name:"Day 1"
172 Added: day ~name:"Day 1"
176 173 [
177 174 pre_exhaust
178 175 ~substitutes:[ "cable-crossovers"; "pec-deck" ]
@@ -185,7 +182,7 @@
185 182 ]
186 183
187 184 let ideal_day_two =
188 Removed: day ~id:"ideal-day-2" ~name:"Day 2"
185 Added: day ~name:"Day 2"
189 186 [
190 187 pre_exhaust
191 188 ~substitutes:[ "straight-arm-pulldowns" ]
@@ -197,7 +194,7 @@
197 194 ]
198 195
199 196 let ideal_day_three =
200 Removed: day ~id:"ideal-day-3" ~name:"Day 3"
197 Added: day ~name:"Day 3"
201 198 [
202 199 pre_exhaust ~substitutes:[ "squats" ] ~isolation:"leg-extensions"
203 200 ~compound:"leg-presses" ();
@@ -206,7 +203,7 @@
206 203 single "sit-ups";
207 204 ]
208 205
209 Removed: let ideal =
206 Added: let[@warning "-32"] ideal =
210 207 make ~name:"Ideal Routine"
211 208 ~workouts:[ ideal_day_one; ideal_day_two; ideal_day_three ]
212 209 end
lib/core/prescription.mli
index 735960d4..3865125b 100644..100644
@@ -42,21 +42,15 @@
42 42 (** Ordered prescribed stimuli. *)
43 43 module Workout : sig
44 44 type t
45 Removed: type id = private string
46 45 type error = Empty_workout
47 46
48 47 exception Invalid of error
49 48
50 Removed: val make : id:string -> name:string -> stimuli:Stimulus.t list -> t
49 Added: val make : name:string -> stimuli:Stimulus.t list -> t
51 50 (** Raises [Invalid Empty_workout] for an empty workout. *)
52 51
53 Removed: val id : t -> id
54 52 val name : t -> string
55 53 val stimuli : t -> Stimulus.t list
56 Removed:
57 Removed: val equal : t -> t -> bool
58 Removed: (** By [id]. *)
59 Removed:
60 54 val pp : Format.formatter -> t -> unit
61 55 end
62 56
@@ -87,7 +81,4 @@
87 81 (** 72h after the final workout. *)
88 82
89 83 val recovery_after : t -> Workout.t -> Recovery.duration
90 Removed:
91 Removed: val ideal : t
92 Removed: (** HD1's three-day routine. *)
93 84 end
test/test_prescription.ml
index fc7df9a1..54b89f84 100644..100644
@@ -25,6 +25,11 @@
25 25 (Prescription.Stimulus.Pre_exhaust
26 26 { isolation = get isolation; compound = get compound })
27 27
28 Added: let pair_with_substitutes ~substitutes ~isolation ~compound =
29 Added: prescribe ~substitutes:(List.map get substitutes)
30 Added: (Prescription.Stimulus.Pre_exhaust
31 Added: { isolation = get isolation; compound = get compound })
32 Added:
28 33 (* {1 One prescribed stimulus} *)
29 34
30 35 let delivery_tests =
@@ -167,13 +172,9 @@
167 172 `Quick,
168 173 fun () ->
169 174 let w =
170 Removed: Prescription.Workout.make ~id:"ideal-day-1" ~name:"Day 1"
171 Removed: ~stimuli:day_one_stimuli
175 Added: Prescription.Workout.make ~name:"Day 1" ~stimuli:day_one_stimuli
172 176 in
173 177 Alcotest.(check string) "name" "Day 1" (Prescription.Workout.name w);
174 Removed: Alcotest.(check string)
175 Removed: "id" "ideal-day-1"
176 Removed: (Prescription.Workout.id w :> string);
177 178 Alcotest.(check int)
178 179 "four stimuli" 4
179 180 (List.length (Prescription.Workout.stimuli w)) );
@@ -182,8 +183,7 @@
182 183 fun () ->
183 184 match
184 185 try
185 Removed: ignore
186 Removed: (Prescription.Workout.make ~id:"empty" ~name:"Nothing" ~stimuli:[]);
186 Added: ignore (Prescription.Workout.make ~name:"Nothing" ~stimuli:[]);
187 187 false
188 188 with
189 189 | Prescription.Workout.Invalid Prescription.Workout.Empty_workout ->
@@ -191,33 +191,60 @@
191 191 with
192 192 | true -> ()
193 193 | false -> Alcotest.fail "expected Empty_workout" );
194 Removed: ( "equality is by id, not by content",
195 Removed: `Quick,
196 Removed: fun () ->
197 Removed: let a =
198 Removed: Prescription.Workout.make ~id:"day-1" ~name:"Day 1"
199 Removed: ~stimuli:day_one_stimuli
200 Removed: in
201 Removed: let renamed =
202 Removed: Prescription.Workout.make ~id:"day-1" ~name:"Renamed"
203 Removed: ~stimuli:[ single "curls" ]
204 Removed: in
205 Removed: let other =
206 Removed: Prescription.Workout.make ~id:"day-2" ~name:"Day 1"
207 Removed: ~stimuli:day_one_stimuli
208 Removed: in
209 Removed: Alcotest.(check bool)
210 Removed: "same id" true
211 Removed: (Prescription.Workout.equal a renamed);
212 Removed: Alcotest.(check bool)
213 Removed: "different id" false
214 Removed: (Prescription.Workout.equal a other) );
215 194 ]
216 195
217 196 (* {1 The routine} *)
218 197
219 198 let secs = Recovery.duration_to_seconds
220 Removed: let ideal = Prescription.Routine.ideal
199 Added:
200 Added: let ideal_day_one =
201 Added: Prescription.Workout.make ~name:"Day 1"
202 Added: ~stimuli:
203 Added: [
204 Added: pair_with_substitutes
205 Added: ~substitutes:[ "cable-crossovers"; "pec-deck" ]
206 Added: ~isolation:"dumbbell-flyes" ~compound:"incline-press";
207 Added: single "laterals";
208 Added: prescribe
209 Added: ~substitutes:[ get "reverse-pec-deck" ]
210 Added: (Prescription.Stimulus.Single (get "bent-over-laterals"));
211 Added: pair_with_substitutes
212 Added: ~substitutes:[ "pressdowns"; "triceps-machine" ]
213 Added: ~isolation:"lying-french-press" ~compound:"dips";
214 Added: ]
215 Added:
216 Added: let ideal_day_two =
217 Added: Prescription.Workout.make ~name:"Day 2"
218 Added: ~stimuli:
219 Added: [
220 Added: pair_with_substitutes
221 Added: ~substitutes:[ "straight-arm-pulldowns" ]
222 Added: ~isolation:"pullovers" ~compound:"close-grip-pulldowns";
223 Added: single "bent-over-rows";
224 Added: single "shrugs";
225 Added: prescribe
226 Added: ~substitutes:[ get "deadlifts" ]
227 Added: (Prescription.Stimulus.Single (get "hyperextensions"));
228 Added: prescribe
229 Added: ~substitutes:[ get "preacher-curls" ]
230 Added: (Prescription.Stimulus.Single (get "curls"));
231 Added: ]
232 Added:
233 Added: let ideal_day_three =
234 Added: Prescription.Workout.make ~name:"Day 3"
235 Added: ~stimuli:
236 Added: [
237 Added: pair_with_substitutes ~substitutes:[ "squats" ]
238 Added: ~isolation:"leg-extensions" ~compound:"leg-presses";
239 Added: single "leg-curls";
240 Added: single "calf-raises";
241 Added: single "sit-ups";
242 Added: ]
243 Added:
244 Added: let ideal =
245 Added: Prescription.Routine.make ~name:"Ideal Routine"
246 Added: ~workouts:[ ideal_day_one; ideal_day_two; ideal_day_three ]
247 Added:
221 248 let days = Prescription.Routine.workouts ideal
222 249
223 250 let nth n =
@@ -319,7 +346,7 @@
319 346 `Quick,
320 347 fun () ->
321 348 let stranger =
322 Removed: Prescription.Workout.make ~id:"elsewhere" ~name:"Elsewhere"
349 Added: Prescription.Workout.make ~name:"Elsewhere"
323 350 ~stimuli:(Prescription.Workout.stimuli (nth 0))
324 351 in
325 352 Alcotest.(check string)