diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-19 13:38:54 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-19 13:38:54 +0200 |
| commit | b26089630a61a54060c86ec26be6dc4fe5418b12 (patch) | |
| tree | cdeb6e17cfcf0a8ecb0bfb59bb2224e04b9a5966 /lib/naming | |
| parent | 45bcbde502e07ad73b96039fcbb62471a3c94781 (diff) | |
| download | colitur-b26089630a61a54060c86ec26be6dc4fe5418b12.tar.gz colitur-b26089630a61a54060c86ec26be6dc4fe5418b12.zip | |
feat(naming): the config file
Owns precedence and provenance and nothing else, and never reads the
filesystem, so it is as testable as the language table.
resolve returns the value AND its source, because a setting that silently
comes from a file the user forgot about is worse than no setting at all --
config --show can then say where each effective value came from.
overlay accumulates rather than last-wins: a user has more than one.
An unknown key is reported, never fatal. A config written for a newer
colitur must still work on an older one, but silently dropping a line the
user wrote is how a typo becomes invisible.
Diffstat (limited to 'lib/naming')
| -rw-r--r-- | lib/naming/config.ml | 43 | ||||
| -rw-r--r-- | lib/naming/config.mli | 28 |
2 files changed, 71 insertions, 0 deletions
diff --git a/lib/naming/config.ml b/lib/naming/config.ml new file mode 100644 index 0000000..ce1b433 --- /dev/null +++ b/lib/naming/config.ml @@ -0,0 +1,43 @@ +module OI = Colitur_kernel.Overlay_ini + +type t = { + lang : string option; + overlays : string list; + template : string option; + format : string option; + unknown_keys : string list; +} + +let empty = { lang = None; overlays = []; template = None; format = None; unknown_keys = [] } + +let lang t = t.lang +let overlays t = t.overlays +let template t = t.template +let format t = t.format +let unknown_keys t = t.unknown_keys + +let of_string text = + match OI.parse_sections text with + | Error e -> Error e + | Ok sections -> ( + match List.find_opt (fun (s : OI.section) -> s.OI.name = "defaults") sections with + | None -> Ok empty + | Some s -> + let acc = + List.fold_left + (fun acc (k, v) -> + match k with + | "lang" -> { acc with lang = Some v } + | "template" -> { acc with template = Some v } + | "format" -> { acc with format = Some v } + (* accumulates: a user has more than one overlay *) + | "overlay" -> { acc with overlays = acc.overlays @ [ v ] } + | other -> { acc with unknown_keys = acc.unknown_keys @ [ other ] }) + empty s.OI.fields + in + Ok acc) + +let resolve ~flag ~config ~default = + match flag with + | Some v -> (v, "flag") + | None -> ( match config with Some v -> (v, "config") | None -> (default, "default")) diff --git a/lib/naming/config.mli b/lib/naming/config.mli new file mode 100644 index 0000000..41ff429 --- /dev/null +++ b/lib/naming/config.mli @@ -0,0 +1,28 @@ +(** The config file: what the user wants by default, and where each value came + from. + + Owns precedence and provenance and nothing else. Never reads the filesystem + -- callers hand it text -- so it is as testable as the language table. + + A config file is OPTIONAL. With none, colitur behaves exactly as it does + without this feature, except that names resolve through the default + language. *) + +type t + +val empty : t +val of_string : string -> (t, string) result + +val lang : t -> string option +val overlays : t -> string list +val template : t -> string option +val format : t -> string option + +(** Keys present in the file that this build does not understand. Reported, never + fatal: a config written for a newer colitur must still work on an older one, + but silently ignoring a line the user wrote is how a typo becomes invisible. *) +val unknown_keys : t -> string list + +(** [resolve ~flag ~config ~default] returns [(value, source)] with source one of + ["flag"], ["config"], ["default"]. Precedence is flag > config > default. *) +val resolve : flag:string option -> config:string option -> default:string -> string * string |
