aboutsummaryrefslogtreecommitdiff
path: root/lib/kernel/layer.mli
blob: ab6e56b7885f3b4812c532685c25894e23941a7e (plain) (blame)
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
(** One calendar layer: a rite's base sanctoral, or a data file of the same
    shape. Entries are canonically sorted by slug. *)
type 'r entry = { date : Date_spec.t; cel : 'r Celebration.t } [@@deriving sexp]
type 'r t = { id : string; name : string; entries : 'r entry list } [@@deriving sexp]

val empty : id:string -> name:string -> 'r t
val of_entries : id:string -> name:string -> 'r entry list -> 'r t
val find : 'r t -> Slug.t -> 'r entry option
val mem : 'r t -> Slug.t -> bool

(** Replaces any entry with the same slug. *)
val set : 'r t -> 'r entry -> 'r t

val remove : 'r t -> Slug.t -> 'r t

(** Date index. Built once per layer, not per year: [Date_spec] dates are
    year-independent. *)
type 'r index

(** [index t ~easter ~years] builds the per-date lookup for [t].

    Fixed entries are keyed (month, day), year-independently, as they always
    were. Movable entries ({!Date_spec.Easter_offset}, {!Date_spec.Nth_weekday})
    have no year-independent key, so they are resolved once for each civil year
    in [years] and keyed by rata die. [easter] supplies that year's Easter as
    the RITE reckons it -- see {!Rite.t}'s own [easter] field.

    [years] must list every civil year the caller's span touches. A liturgical
    year is Advent-anchored and straddles two, so {!Calendar.year} and
    {!Validate.run} both pass [[y; y + 1]]. A movable entry whose year is
    omitted is simply absent from the index -- silently, so getting [years]
    wrong loses celebrations rather than erroring.

    NOTE the index is therefore no longer built once per layer independent of
    year: for fixed entries it still is, for movable ones it is per-span. *)
val index : 'r t -> easter:(int -> Date.t) -> years:int list -> 'r index

(** Entries falling on [date], fixed and movable together, in the layer's
    canonical slug order. *)
val on_date : 'r index -> Date.t -> 'r entry list

(** Loads a layer from a sexp file. Parse and validation failures come back as
    [Error], never as an exception. *)
val load : (Sexplib0.Sexp.t -> 'r) -> string -> ('r t, string) result