aboutsummaryrefslogtreecommitdiff
path: root/lib/kernel/overlay_ini.mli
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/overlay_ini.mli')
-rw-r--r--lib/kernel/overlay_ini.mli69
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/kernel/overlay_ini.mli b/lib/kernel/overlay_ini.mli
new file mode 100644
index 0000000..bace93b
--- /dev/null
+++ b/lib/kernel/overlay_ini.mli
@@ -0,0 +1,69 @@
+(** A flat INI front end for overlay files.
+
+ This is a CONVENIENCE FORMAT, not a second data model. It parses to exactly
+ the {!Overlay.t} the S-expression form parses to, and everything downstream
+ -- merge, diagnostics, validation -- is the same code on the same values.
+ There is deliberately no second semantics to keep in step.
+
+ It is also deliberately LESS EXPRESSIVE than the sexp form. It covers [Add],
+ [Suppress] and single-field [Edit], which is what a diocesan or parish
+ calendar needs; [Replace], multi-field edits and citation edits are not
+ expressible and the parser says so by name rather than failing obscurely.
+ Anything it cannot say is a reason to write sexp, not a reason to grow this.
+
+ {1 Format}
+
+ Section names are slugs. A [\[overlay\]] section carries the file's id.
+
+ {v
+ [overlay]
+ id = my-parish
+
+ [our-patron]
+ date = 07-11
+ rank = class-3
+ colour = white
+ name.en = St Example, Patron
+
+ [some-universal-slug]
+ suppress = yes
+ v}
+
+ Dates take three forms, matching {!Date_spec}: [MM-DD], [easter+N] or
+ [easter-N], and [mon/day/nth] such as [oct/sun/1] or [oct/sun/-1]. *)
+
+(** [parse ~rank_of_string text] is the overlay [text] denotes.
+
+ [rank_of_string] is supplied by the rite, exactly as [Overlay.load] takes
+ [rank_of_sexp]: the kernel does not know one rite's rank vocabulary from
+ another's.
+
+ Errors carry the section name and the offending value, never a source-file
+ path -- this format exists for people who are not reading the source. *)
+val parse :
+ rank_of_string:(string -> 'r option) -> string -> ('r Overlay.t, string) result
+
+(** [to_sexp_string t] renders [t] as the S-expression form, with a header
+ noting that it was generated. *)
+val to_sexp_string : ('r -> Sexplib0.Sexp.t) -> 'r Overlay.t -> string
+
+(** [convert ~rank_of_string ~rank_to_sexp ~rank_of_sexp text] parses [text],
+ renders it, and PROVES the rendering before returning it: the emitted text
+ is parsed back with the very function the engine uses to load an overlay,
+ and the result must equal what the INI denoted.
+
+ That check is the point of this module. A transpiler that emits
+ syntactically valid but semantically wrong output is the failure mode a
+ convenience format invites, and it is one [colitur check] could not catch,
+ since the emitted file would parse cleanly and simply mean something else.
+ Verifying the round trip here makes that class of bug impossible to ship
+ rather than merely unlikely.
+
+ [Error] on a parse failure, and on a round-trip mismatch -- which is a bug
+ in this module, and says so. *)
+val convert :
+ rank_of_string:(string -> 'r option) ->
+ rank_to_sexp:('r -> Sexplib0.Sexp.t) ->
+ rank_of_sexp:(Sexplib0.Sexp.t -> 'r) ->
+ string ->
+ (string, string) result