diff options
Diffstat (limited to 'lib/kernel/overlay_ini.mli')
| -rw-r--r-- | lib/kernel/overlay_ini.mli | 69 |
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 |
