@@ -28,155 +28,6 @@ let contact_kind_of_yaml = function
2828type contact = [% import: Data_intf.Governance .contact ]
2929[@@ deriving of_yaml , show ]
3030
31- type weekday = [% import: Data_intf.Governance .weekday ] [@@ deriving show ]
32-
33- let weekday_of_yaml = function
34- | `String "mon" | `String "monday" -> Ok Mon
35- | `String "tue" | `String "tuesday" -> Ok Tue
36- | `String "wed" | `String "wednesday" -> Ok Wed
37- | `String "thu" | `String "thursday" -> Ok Thu
38- | `String "fri" | `String "friday" -> Ok Fri
39- | `String "sat" | `String "saturday" -> Ok Sat
40- | `String "sun" | `String "sunday" -> Ok Sun
41- | x -> (
42- match Yaml. to_string x with
43- | Ok s -> Error (`Msg (" Unknown weekday: " ^ s))
44- | Error _ -> Error (`Msg " Unknown weekday" ))
45-
46- type recurrence_rule = [% import: Data_intf.Governance .recurrence_rule ]
47- [@@ deriving show ]
48-
49- let recurrence_rule_of_yaml = function
50- | `O fields -> (
51- let field name =
52- Option. to_result
53- ~none: (`Msg (" Missing recurrence field: " ^ name))
54- (List. assoc_opt name fields)
55- in
56- let int_field name =
57- let ( let * ) = Result. bind in
58- let * value = field name in
59- match value with
60- | `Float f ->
61- if Float. is_integer f then Ok (int_of_float f)
62- else Error (`Msg (" Invalid integer for field: " ^ name))
63- | `String s -> (
64- match int_of_string_opt s with
65- | Some v -> Ok v
66- | None -> Error (`Msg (" Invalid integer for field: " ^ name)))
67- | _ -> Error (`Msg (" Invalid integer for field: " ^ name))
68- in
69- let rec parse_weekdays acc = function
70- | [] -> Ok (List. rev acc)
71- | x :: xs ->
72- let ( let * ) = Result. bind in
73- let * weekday = weekday_of_yaml x in
74- parse_weekdays (weekday :: acc) xs
75- in
76- let ( let * ) = Result. bind in
77- let * kind = field " kind" in
78- match kind with
79- | `String "weekly" ->
80- let * interval_weeks = int_field " interval_weeks" in
81- let * () =
82- if interval_weeks > = 1 then Ok ()
83- else Error (`Msg " interval_weeks must be >= 1" )
84- in
85- let * byweekday = field " byweekday" in
86- let * byweekday =
87- match byweekday with
88- | `A weekdays -> parse_weekdays [] weekdays
89- | _ -> Error (`Msg " Invalid recurrence field: byweekday" )
90- in
91- let * () =
92- if byweekday <> [] then Ok ()
93- else Error (`Msg " byweekday must not be empty" )
94- in
95- Ok (Weekly { interval_weeks; byweekday })
96- | `String "monthly_by_nth_weekday" ->
97- let * interval_months = int_field " interval_months" in
98- let * () =
99- if interval_months > = 1 then Ok ()
100- else Error (`Msg " interval_months must be >= 1" )
101- in
102- let * nth = int_field " nth" in
103- let * () =
104- if nth > = 1 && nth < = 5 then Ok ()
105- else Error (`Msg " nth must be between 1 and 5" )
106- in
107- let * weekday = field " weekday" in
108- let * weekday = weekday_of_yaml weekday in
109- Ok (Monthly_by_nth_weekday { interval_months; nth; weekday })
110- | _ ->
111- Error
112- (`Msg
113- " Invalid recurrence rule kind. Expected weekly or \
114- monthly_by_nth_weekday" ))
115- | _ ->
116- Error
117- (`Msg
118- " Invalid recurrence rule. Expected kind=weekly or \
119- kind=monthly_by_nth_weekday" )
120-
121- type recurrence = [% import: Data_intf.Governance .recurrence ] [@@ deriving show ]
122-
123- let validate_starts_at starts_at =
124- let is_digit c = c > = '0' && c < = '9' in
125- let expected_len = 19 in
126- let fail msg =
127- Error (`Msg (" Invalid starts_at value '" ^ starts_at ^ " ': " ^ msg))
128- in
129- if String. length starts_at <> expected_len then
130- fail " expected format YYYY-MM-DDTHH:MM:SS"
131- else if
132- not
133- (is_digit starts_at.[0 ]
134- && is_digit starts_at.[1 ]
135- && is_digit starts_at.[2 ]
136- && is_digit starts_at.[3 ]
137- && starts_at.[4 ] = '-'
138- && is_digit starts_at.[5 ]
139- && is_digit starts_at.[6 ]
140- && starts_at.[7 ] = '-'
141- && is_digit starts_at.[8 ]
142- && is_digit starts_at.[9 ]
143- && starts_at.[10 ] = 'T'
144- && is_digit starts_at.[11 ]
145- && is_digit starts_at.[12 ]
146- && starts_at.[13 ] = ':'
147- && is_digit starts_at.[14 ]
148- && is_digit starts_at.[15 ]
149- && starts_at.[16 ] = ':'
150- && is_digit starts_at.[17 ]
151- && is_digit starts_at.[18 ])
152- then fail " expected format YYYY-MM-DDTHH:MM:SS"
153- else
154- match Ptime. of_rfc3339 (starts_at ^ " +00:00" ) with
155- | Ok _ -> Ok ()
156- | Error _ -> fail " contains an invalid date or time component"
157-
158- type recurrence_metadata = {
159- starts_at : string ;
160- timezone : string ;
161- duration_minutes : int ;
162- rule : recurrence_rule ;
163- }
164- [@@ deriving of_yaml , stable_record ~version: Data_intf.Governance .recurrence ]
165-
166- let recurrence_of_yaml yml =
167- let ( let * ) = Result. bind in
168- let * recurrence = recurrence_metadata_of_yaml yml in
169- let * () = validate_starts_at recurrence.starts_at in
170- let * () =
171- if String. trim recurrence.timezone <> " " then Ok ()
172- else Error (`Msg " timezone must not be empty" )
173- in
174- let * () =
175- if recurrence.duration_minutes > = 1 then Ok ()
176- else Error (`Msg " duration_minutes must be >= 1" )
177- in
178- Ok (recurrence_metadata_to_Data_intf_Governance_recurrence recurrence)
179-
18031type dev_meeting = [% import: Data_intf.Governance .dev_meeting ] [@@ deriving show ]
18132
18233type dev_meeting_metadata = {
@@ -186,7 +37,6 @@ type dev_meeting_metadata = {
18637 ical : string option ; [@ default None ]
18738 calendar : string option ; [@ default None ]
18839 notes : string ;
189- recurrences : recurrence list ; [@ default []]
19040}
19141[@@ deriving of_yaml , stable_record ~version: Data_intf.Governance .dev_meeting ]
19242
0 commit comments