package cmdlang-stdlib-runner

  1. Overview
  2. Docs
A basic execution runner for cmdlang based on stdlib.arg

Install

dune-project
 Dependency

Authors

Maintainers

Sources

cmdlang-0.0.10.tbz
sha256=ca68da238799022810373d060bbd528d1de7687e8f8b4a89450c0bb33a41897d
sha512=7e223e3b02da4132f3638c83cad2b0b5bd3f672d777ad09a1d956db6bbed8d93b6125d754fcc0d970b16ac8150be08f9c3ae6a066868e2128351f9e049fefe53

doc/src/cmdlang-stdlib-runner/param_parser.ml.html

Source file param_parser.ml

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
78
79
80
81
82
(*********************************************************************************)
(*  cmdlang - Declarative command-line parsing for OCaml                         *)
(*  SPDX-FileCopyrightText: 2024-2025 Mathieu Barbin <mathieu.barbin@gmail.com>  *)
(*  SPDX-License-Identifier: MIT                                                 *)
(*********************************************************************************)

let rec eval : type a. a Ast.Param.t -> string -> a Ast.or_error_msg =
  fun (type a) (param : a Ast.Param.t) (str : string) : a Ast.or_error_msg ->
  let err msg = Error (`Msg msg) in
  match param with
  | Conv { docv = _; of_string; to_string = _ } -> of_string str
  | String -> Ok str
  | Int ->
    (match int_of_string_opt str with
     | Some a -> Ok a
     | None -> err (Printf.sprintf "invalid value %S (not an int)" str))
  | Float ->
    (match float_of_string_opt str with
     | Some a -> Ok a
     | None -> err (Printf.sprintf "invalid value %S (not a float)" str))
  | Bool ->
    (match bool_of_string_opt str with
     | Some a -> Ok a
     | None -> err (Printf.sprintf "invalid value %S (not a bool)" str))
  | File -> Ok str
  | Enum { docv = _; choices = hd :: tl; to_string = _ } ->
    (match hd :: tl |> List.find_opt (fun (choice, _) -> String.equal choice str) with
     | Some (_, a) -> Ok a
     | None -> err (Printf.sprintf "invalid value %S (not a valid choice)" str))
  | Comma_separated param ->
    let params = String.split_on_char ',' str in
    let oks, errors =
      params
      |> List.partition_map (fun str ->
        match eval param str with
        | Ok a -> Either.Left a
        | Error (`Msg m) -> Either.Right m)
    in
    (match errors with
     | [] -> Ok oks
     | _ :: _ as msgs -> err (String.concat ", " msgs))
;;

let docv : type a. a Ast.Param.t -> docv:string option -> string =
  fun param ~docv ->
  let rec aux : type a. a Ast.Param.t -> docv:string option -> string =
    fun (type a) (param : a Ast.Param.t) ~docv ->
    match docv with
    | Some v -> v
    | None ->
      let or_val = function
        | Some v -> v
        | None -> "VAL"
      in
      (match param with
       | Conv { docv; of_string = _; to_string = _ } -> or_val docv
       | String -> "STRING"
       | Int -> "INT"
       | Float -> "FLOAT"
       | Bool -> "BOOL"
       | File -> "FILE"
       | Enum { docv; choices = _; to_string = _ } -> or_val docv
       | Comma_separated param -> aux param ~docv:None)
  in
  aux param ~docv
;;

let rec print : type a. a Ast.Param.t -> a -> string =
  fun (type a) (param : a Ast.Param.t) (a : a) : string ->
  match param with
  | Conv { docv = _; of_string = _; to_string } -> to_string a
  | String -> a
  | Int -> string_of_int a
  | Float -> string_of_float a
  | Bool -> string_of_bool a
  | File -> a
  | Enum { docv = _; choices = hd :: tl; to_string } ->
    (match hd :: tl |> List.find_opt (fun (_, b) -> a == b) with
     | Some (s, _) -> s
     | None -> to_string a)
  | Comma_separated param -> a |> List.map (fun a -> print param a) |> String.concat ", "
;;