···88open Message
99open Result.Syntax
10101111-(* type keys = (Toml.Types.Table.key
1212- [@printer fun fmt key -> fprintf fmt "%s" (Toml.Types.Table.Key.to_string
1313- key)]) list list [@@deriving show] *)
1414-1511module Key_set = struct
1612 include Set.Make (struct
1713 type t = Toml.Types.Table.key list
···2521 remove key set
2622end
27232424+let pp_dirlist fmt key =
2525+ Format.(
2626+ fprintf fmt "[%a]"
2727+ (pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt "; ") pp_print_string)
2828+ key)
2929+2830let keys (tbl : Toml.Types.value Toml.Types.Table.t) =
2931 let rec go current keys tbl =
3032 List.fold_left
···4345let parse lexbuf filename : Config.t res =
4446 match Toml.Parser.parse lexbuf filename with
4547 | `Error (desc, {source; _}) ->
4646- let loc = Range.of_lexbuf ~source:(`File source) lexbuf in
4747- error @@ Diagnostic.createf Error ~code:Configuration_error "%s" desc
4848+ let range = Range.of_lexbuf ~source:(`File source) lexbuf in
4949+ error
5050+ @@ Diagnostic.createf Error
5151+ ~labels:[Error.empty_label ~range]
5252+ ~code:Configuration_error "%s" desc
4853 | `Ok tbl ->
4954 let open Toml.Lenses in
5055 let keys = ref (keys tbl) in
5151- let with_default ~value k lens =
5656+ let with_default ~value ~pp_value k lens =
5257 let open Toml.Lenses in
5358 match get tbl lens with
5454- | None -> value
5959+ | None ->
6060+ Error.print
6161+ @@ Diagnostic.createf Warning "option [%a] not set, using default %a"
6262+ Format.(
6363+ pp_print_list
6464+ ~pp_sep:(fun fmt () -> fprintf fmt ".")
6565+ pp_print_string)
6666+ k pp_value value;
6767+ value
5568 | Some v ->
5669 keys := Key_set.remove k !keys;
5770 v
···7386 let default = Config.default ~url () in
7487 let trees =
7588 let k = ["forest"; "trees"] in
7676- with_default ~value:default.trees k
8989+ with_default ~value:default.trees ~pp_value:pp_dirlist k
7790 (forest |-- key "trees" |-- array |-- strings)
7891 in
7992 let errors, foreign =
···95108 in
96109 match get foreign_tbl (key "path" |-- string) with
97110 | None ->
9898- error
9999- @@ [Diagnostic.createf Error ~code:Required_config_option "path"]
111111+ error @@ Diagnostic.createf Error ~code:Required_config_option "path"
100112 | Some path -> ok Config.{path; route_locally; include_in_manifest})
101113 in
102114 let assets =
103103- with_default ~value:default.assets ["forest"; "assets"]
115115+ with_default ~value:default.assets ~pp_value:pp_dirlist
116116+ ["forest"; "assets"]
104117 (forest |-- key "assets" |-- array |-- strings)
105118 in
106119 let home =
107120 let k = ["forest"; "home"] in
108121 URI.named_uri ~base:url
109109- @@ with_default ~value:"index" k (forest |-- key "home" |-- string)
122122+ @@ with_default ~value:"index" ~pp_value:Format.pp_print_string k
123123+ (forest |-- key "home" |-- string)
110124 in
111125 let theme = get tbl (forest |-- key "theme" |-- string) in
112126 (if not (Key_set.is_empty !keys) then
113127 let unused_keys =
114128 !keys |> Key_set.to_list
115115- |> List.map (List.map Toml.Types.Table.Key.to_string)
129129+ |> List.map
130130+ (List.map Toml.Types.Table.Key.to_string >>> String.concat ".")
116131 in
117117- Error.print_warning ~code:Uninterpreted_config_options "");
132132+ Error.print
133133+ @@ Diagnostic.createf Warning
134134+ "These configuration options are unknown: %a"
135135+ Format.(
136136+ pp_print_list
137137+ ~pp_sep:(fun fmt () -> fprintf fmt "@.")
138138+ pp_print_string)
139139+ unused_keys);
140140+ List.iter Error.print errors;
118141 ok @@ Config.{url; assets; trees; foreign; home; theme}
119142120143let parse_forest_config_string str =
···129152 let result = parse lexbuf filename in
130153 Sys.chdir @@ Filename.dirname filename;
131154 result
132132- with exn ->
133133- error @@ Diagnostic.createf Error ~code:IO_error "%a" Eio.Exn.pp exn
155155+ with Sys_error exn ->
156156+ error @@ Diagnostic.createf Error ~code:IO_error "%s" exn
+6
lib/frontend/test/Test_config_parser.ml
···11+open Forester_frontend
22+33+let () =
44+ match Config_parser.parse_forest_config_file Sys.argv.(1) with
55+ | Ok _ -> ()
66+ | Error d -> Forester_core.Error.print d
+12
lib/frontend/test/config.t
···11+ $ parse_forester_config configs/correct.toml
22+33+ $ parse_forester_config configs/missing-fields.toml
44+ warning: option [forest.trees] not set, using default [trees]
55+ warning: option [forest.assets] not set, using default []
66+ warning: option [forest.home] not set, using default index
77+88+ $ parse_forester_config configs/uninterpreted-fields.toml
99+ warning: These configuration options are unknown: forest.unknown
1010+1111+ $ parse_forester_config configs/nonexistent.toml
1212+ error[io_error]: configs/nonexistent.toml: No such file or directory