Source file search_param.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
type t =
| Time_slots of {
search_using_tz_offset_s : Time.tz_offset_s option;
time_slots : Time_slot.t list;
}
| Years_ahead_start_unix_second of {
search_using_tz_offset_s : Time.tz_offset_s option;
start : int64;
search_years_ahead : int;
}
| Years_ahead_start_date_time of {
search_using_tz_offset_s : Time.tz_offset_s option;
start : Time.Date_time.t;
search_years_ahead : int;
}
type error =
| Invalid_start
| Invalid_time_slots
| Invalid_search_years_ahead
| Too_far_into_future
let search_using_tz_offset_s_of_search_param (param : t) :
Time.tz_offset_s option =
match param with
| Time_slots { search_using_tz_offset_s; _ } -> search_using_tz_offset_s
| Years_ahead_start_unix_second { search_using_tz_offset_s; _ } ->
search_using_tz_offset_s
| Years_ahead_start_date_time { search_using_tz_offset_s; _ } ->
search_using_tz_offset_s
let push_search_param_to_later_start ~(start : int64) (search_param : t) :
(t, unit) result =
match search_param with
| Time_slots { search_using_tz_offset_s; time_slots } -> (
match Time_slots.Bound.min_start_and_max_end_exc_list time_slots with
| None -> Ok search_param
| Some (start', end_exc') ->
let start = max start' start in
let time_slots =
time_slots
|> List.to_seq
|> Time_slots.inter (Seq.return (start, end_exc'))
|> List.of_seq
in
Ok (Time_slots { search_using_tz_offset_s; time_slots }) )
| Years_ahead_start_unix_second
{ search_using_tz_offset_s; start = start'; search_years_ahead } ->
let start = max start' start in
Ok
(Years_ahead_start_unix_second
{ search_using_tz_offset_s; start; search_years_ahead })
| Years_ahead_start_date_time
{ search_using_tz_offset_s; start = start'; search_years_ahead } -> (
match Time.Date_time.to_unix_second start' with
| Error () -> Error ()
| Ok start' ->
let start = max start' start in
Time.Date_time.of_unix_second
~tz_offset_s_of_date_time:search_using_tz_offset_s start
|> Result.map (fun start ->
Years_ahead_start_date_time
{ search_using_tz_offset_s; start; search_years_ahead }) )
let start_date_time_and_search_years_ahead_of_search_param (search_param : t) :
(Time.Date_time.t * int) option =
match search_param with
| Time_slots { search_using_tz_offset_s; time_slots } -> (
match Time_slots.Bound.min_start_and_max_end_exc_list time_slots with
| None -> None
| Some (start, end_exc) ->
let start =
Time.Date_time.of_unix_second
~tz_offset_s_of_date_time:search_using_tz_offset_s start
|> Result.get_ok
in
let end_exc =
Time.Date_time.of_unix_second
~tz_offset_s_of_date_time:search_using_tz_offset_s end_exc
|> Result.get_ok
in
let search_years_ahead = end_exc.year - start.year + 1 in
Some (start, search_years_ahead) )
| Years_ahead_start_unix_second
{ search_using_tz_offset_s; start; search_years_ahead } ->
let start =
Time.Date_time.of_unix_second
~tz_offset_s_of_date_time:search_using_tz_offset_s start
|> Result.get_ok
in
Some (start, search_years_ahead)
| Years_ahead_start_date_time
{ search_using_tz_offset_s = _; start; search_years_ahead } ->
Some (start, search_years_ahead)
module Check = struct
let check_search_param (x : t) : (unit, error) result =
match x with
| Time_slots { search_using_tz_offset_s = _; time_slots } ->
if
List.for_all
(fun (x, y) ->
Time_slot.Check.is_valid (x, y)
&& Time.Date_time.of_unix_second ~tz_offset_s_of_date_time:None x
|> Result.is_ok
&& Time.Date_time.of_unix_second ~tz_offset_s_of_date_time:None y
|> Result.is_ok)
time_slots
then Ok ()
else Error Invalid_time_slots
| Years_ahead_start_unix_second
{ search_using_tz_offset_s; start; search_years_ahead } -> (
match
Time.Date_time.of_unix_second
~tz_offset_s_of_date_time:search_using_tz_offset_s start
with
| Error () -> Error Invalid_start
| Ok start ->
if search_years_ahead <= 0 then Error Invalid_search_years_ahead
else if start.year + search_years_ahead > Time.Date_time.max.year
then Error Too_far_into_future
else Ok () )
| Years_ahead_start_date_time
{ search_using_tz_offset_s = _; start; search_years_ahead } ->
if Time.Check.date_time_is_valid start then
if search_years_ahead <= 0 then Error Invalid_search_years_ahead
else if start.year + search_years_ahead > Time.Date_time.max.year then
Error Too_far_into_future
else Ok ()
else Error Invalid_start
end