geochan/src/virtual/make_config_lib.ml

198 lines
5.3 KiB
OCaml
Raw Normal View History

2025-05-30 05:42:50 +02:00
module Schema = struct
type nil = N
type empty = E
(*type dir = D*)
type _ kind =
| Bool : bool kind
| Int : int kind
| Float : float kind
| String : string kind
(* todo: one general gadt for params and schema? *)
type _ params =
| Nil : nil params
| Cons : ('a kind * 'b params) -> ('a * 'b) params
type _ schema =
| Empty : empty schema
| Dir : (string * 'a params * 'b schema) -> ('a * 'b) schema
let v = Dir ("void", Nil, Empty)
let v1 = Dir ("cc", Cons (String, Nil), v)
let v2 =
Dir
( "salut"
, Cons (String, Cons (Bool, Cons (Float, Nil)))
, Dir ("euj", Cons (Int, Nil), v1) )
end
(* ------ *)
type _ tag =
| String : string tag
| Bool : bool tag
| Int : int tag
| Option : 'a tag -> 'a option tag
| List : 'a tag -> 'a list tag
| Array : 'a tag -> 'a array tag
| Fpath : Fpath.t tag
| Uri : Uri.t tag
type w = W : 'a tag -> w
let rec str_aux : type a. a tag -> a -> string =
fun tag v ->
match tag with
| String -> Fmt.str {|"%s"|} v
| Bool -> Fmt.str {|%b|} v
| Int -> Fmt.str {|%d|} v
| Option subtag -> (
match v with
| None -> "None"
| Some v -> Fmt.str "Some ( %s )" (str_aux subtag v) )
| List subtag -> (
match v with
| [] -> "[]"
| l ->
let l = List.map (fun v -> str_aux subtag v) l in
Fmt.str "[ %s ]" (String.concat "; " l) )
| Array subtag -> (
match v with
| [||] -> "[||]"
| l ->
let l = Array.map (fun v -> str_aux subtag v) l |> Array.to_list in
Fmt.str "[| %s |]" (String.concat "; " l) )
| Fpath ->
Fmt.str {|Result.get_ok (Fpath.of_string "%s")|} (Fpath.to_string v)
| Uri -> Fmt.str {|Uri.of_string "%s"|} (Uri.to_string v)
let str : type a. a tag -> string -> a -> string =
fun tag k v ->
match tag with
| List _ -> Fmt.str {|let %s_l = %s@.|} k (str_aux tag v)
| _ -> Fmt.str {|let %s = %s@.|} k (str_aux tag v)
2024-05-29 19:16:48 +02:00
let config_path =
2025-05-30 05:42:50 +02:00
let config_dir =
match Dir.config with
| None -> Fmt.failwith "can't compute configuration directory"
| Some config_dir -> config_dir
2024-05-29 19:16:48 +02:00
in
let config_path = Fpath.(config_dir / "config.scfg") in
config_path
let config =
2025-05-30 05:42:50 +02:00
let exists = Bos.OS.File.exists config_path in
let config =
2024-05-29 19:16:48 +02:00
match exists with
2025-05-30 05:42:50 +02:00
| Error (`Msg s) -> Fmt.failwith "%s" s
| Ok false ->
Fmt.failwith "configuration file `%a` does not exist, please create it"
2024-05-29 19:16:48 +02:00
Fpath.pp config_path
2025-05-30 05:42:50 +02:00
| Ok true -> Scfg.Parse.from_file config_path
2024-05-29 19:16:48 +02:00
in
2025-05-30 05:42:50 +02:00
config |> Result.get_ok
let get : type a. a tag -> string -> a =
fun tag k ->
let open Scfg.Query in
let dir = get_dir_exn k config in
match tag with
| String -> get_param_exn 0 dir
| Bool -> get_param_bool_exn 0 dir
| Int -> get_param_int_exn 0 dir
| Option Int -> (
let n = Scfg.Query.get_param_int_exn 0 dir in
2024-05-29 19:16:48 +02:00
match n with
2025-05-30 05:42:50 +02:00
| -1 -> None
| n when n < 0 -> Fmt.failwith "negative `%s` value" k
| n -> Some n )
| List String ->
let dirs = Scfg.Query.get_dirs k config in
2024-05-29 19:16:48 +02:00
List.map
(fun dir ->
2025-05-30 05:42:50 +02:00
let v = Scfg.Query.get_param_exn 0 dir in
2024-05-29 19:16:48 +02:00
v )
dirs
2025-05-30 05:42:50 +02:00
| Option _ | List _ | Array _ | Fpath | Uri -> Fmt.failwith "unimplemented"
let mk : type a. a tag -> string -> unit =
fun tag k ->
let v = get tag k in
let str = str tag k v in
Fmt.pr "%s" str
2024-05-29 19:16:48 +02:00
let print_config_serv () =
2025-05-30 05:42:50 +02:00
Fmt.pr "%s" (str Fpath "config_path" config_path);
let data_dir = Dir.data |> Option.get in
(* create data_dir *)
2024-05-29 19:16:48 +02:00
let () =
2025-05-30 05:42:50 +02:00
match Bos.OS.Dir.create data_dir with
| Ok true -> ()
| Ok false -> ()
| Error (`Msg _) -> Fmt.failwith "error when creating %a" Fpath.pp data_dir
2024-05-29 19:16:48 +02:00
in
2025-05-30 05:42:50 +02:00
let db_path = Fpath.(data_dir / "geochan.db") in
let uri = Uri.of_string @@ Fmt.str "sqlite3://%a" Fpath.pp db_path in
Fmt.pr "%s" (str Uri "db_uri" uri);
let l =
[ (W Bool, "default_logger")
; (W Bool, "custom_logger")
; (* TODO add temporary password hash + email for first connection? *)
(W (List String), "admin")
]
2024-05-29 19:16:48 +02:00
in
2025-05-30 05:42:50 +02:00
List.iter (fun (W tag, k) -> mk tag k) l;
2024-05-29 19:16:48 +02:00
()
(* config (server & client) *)
let print_config () =
2025-05-30 05:42:50 +02:00
let l =
[ (W String, "source_code_url")
; (W String, "hostname")
; (W Int, "port")
; (W Int, "csrf_lifetime")
; (W Int, "session_lifetime")
; (W Bool, "open_registration")
; (W Int, "thread_max_count")
; (W Int, "thread_alive_max_count")
; (W Int, "thread_replies_max_count")
; (W Int, "subject_max_length")
; (W (Option Int), "subject_min_length")
; (W Int, "comment_max_length")
; (W (Option Int), "comment_min_length")
; (W Int, "report_max_length")
; (W Int, "nick_max_length")
; (W Int, "nick_min_length")
; (W Int, "biography_max_length")
; (W Int, "password_max_length")
; (W Int, "password_min_length")
; (W Int, "image_name_max_length")
; (W Int, "image_description_max_length")
; (W Int, "image_max_size")
]
in
List.iter (fun (W tag, k) -> mk tag k) l;
Fmt.pr "%s"
(str (Array String) "supported_mime_type"
[| "image/jpeg"; "image/png"; "image/webp"; "image/gif" |] );
2024-05-29 19:16:48 +02:00
()
let () =
2025-05-30 05:42:50 +02:00
let arg =
if Array.length Sys.argv > 1 then Sys.argv.(1)
else Fmt.failwith "make config failure, no argument provided"
2024-05-29 19:16:48 +02:00
in
2025-05-30 05:42:50 +02:00
let () =
2024-05-29 19:16:48 +02:00
match arg with
2025-05-30 05:42:50 +02:00
| "--config-serv" -> print_config_serv ()
| "--config" -> print_config ()
| _ -> Fmt.failwith "make config failure, invalid argument `%s`" arg
2024-05-29 19:16:48 +02:00
in
()