summaryrefslogtreecommitdiff
path: root/src/vyconf_config.ml
blob: 6c24ffbc045123c7cf0443dc98c875d6d3b6c501 (plain)
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
exception Missing_field of string

type t = {
    app_name: string;
    data_dir: string;
    program_dir: string;
    config_dir: string;
    primary_config: string;
    fallback_config: string;
    socket: string;
    pid_file: string;
    log_file: string option;
    log_template: string;
    log_level: string;
} [@@deriving show]

(* XXX: there should be a better way than to fully initialize it
        with garbage just to update it later *)
let empty_config = {
    app_name = "";
    data_dir = "";
    program_dir = "";
    config_dir = "";
    primary_config = "";
    fallback_config = "";
    socket = "";
    pid_file = "";
    log_file = None;
    log_template = "";
    log_level = "";
}


(* XXX: We assume that nesting in TOML config files never goes beyond two levels  *)

let get_field conf tbl_name field_name =
    (* NB: TomlLenses module uses "table" and "field" names for function names,
            hence tbl_name and field_name
     *)
    TomlLenses.(get conf (key tbl_name |-- table |-- key field_name |-- string))

let mandatory_field conf table field =
    let value = get_field conf table field in
    match value with
    | Some value -> value
    | None -> raise @@ Missing_field (Printf.sprintf "Invalid config: Missing mandatory field \"%s\" in section [%s]" field table)

let optional_field default conf table field =
    let value = get_field conf table field in
    Util.substitute_default value default

let load filename =
    try
        let open Defaults in
        let conf_toml = Toml.Parser.from_filename filename |> Toml.Parser.unsafe in
        let conf = empty_config in
            (* Mandatory fields *)
            let conf = {conf with app_name = mandatory_field conf_toml "appliance" "name"} in
            let conf = {conf with data_dir = mandatory_field conf_toml "appliance" "data_dir"} in
            let conf = {conf with config_dir = mandatory_field conf_toml "appliance" "config_dir"} in
            let conf = {conf with program_dir = mandatory_field conf_toml "appliance" "program_dir"} in
            let conf = {conf with primary_config = mandatory_field conf_toml "appliance" "primary_config"} in
            let conf = {conf with fallback_config = mandatory_field conf_toml "appliance" "fallback_config"} in
            (* Optional fields *)
            let conf = {conf with pid_file = optional_field defaults.pid_file conf_toml "vyconf" "pid_file"} in
            let conf = {conf with socket = optional_field defaults.socket conf_toml "vyconf" "socket"} in
            let conf = {conf with log_template = optional_field defaults.log_template conf_toml "vyconf" "log_template"} in
            let conf = {conf with log_level = optional_field defaults.log_level conf_toml "vyconf" "log_level"} in
            (* log_file is already string option, so we don't need to unwrap *)
            let conf = {conf with log_file = get_field conf_toml "vyconf" "log_file"} in
            Result.Ok conf
    with
    | Sys_error msg -> Error msg
    | Toml.Parser.Error (msg, _) -> Error msg
    | Missing_field msg -> Error msg

let dump  = show