56 lines
1.5 KiB
OCaml
56 lines
1.5 KiB
OCaml
|
type t = A of string [@@unboxed]
|
||
|
|
||
|
let invalid_argf fmt = Printf.ksprintf invalid_arg fmt
|
||
|
|
||
|
type syntax = Jbuild | Dune
|
||
|
|
||
|
let string_of_syntax = function
|
||
|
| Jbuild -> "jbuild"
|
||
|
| Dune -> "dune"
|
||
|
|
||
|
let (is_valid_jbuild, is_valid_dune) =
|
||
|
let rec jbuild s i len =
|
||
|
i = len ||
|
||
|
match String.unsafe_get s i with
|
||
|
| '"' | '(' | ')' | ';' | '\000'..'\032' | '\127'..'\255' -> false
|
||
|
| _ -> jbuild s (i + 1) len
|
||
|
in
|
||
|
let rec dune s i len =
|
||
|
i = len ||
|
||
|
match String.unsafe_get s i with
|
||
|
| '%' | '"' | '(' | ')' | ';' | '\000'..'\032' | '\127'..'\255' -> false
|
||
|
| _ -> dune s (i + 1) len
|
||
|
in
|
||
|
let make looper s =
|
||
|
let len = String.length s in
|
||
|
len > 0 && looper s 0 len
|
||
|
in
|
||
|
(make jbuild, make dune)
|
||
|
|
||
|
let of_string syn s =
|
||
|
match syn with
|
||
|
| Jbuild when is_valid_jbuild s -> Some (A s)
|
||
|
| Dune when is_valid_dune s -> Some (A s)
|
||
|
| _ -> None
|
||
|
|
||
|
let of_string_exn syn s =
|
||
|
match of_string syn s with
|
||
|
| Some s -> s
|
||
|
| None ->
|
||
|
invalid_argf "'%s' is not a valid %s atom" s (string_of_syntax syn)
|
||
|
|
||
|
let to_string (A t) syntax =
|
||
|
match syntax with
|
||
|
| Jbuild -> t
|
||
|
| Dune ->
|
||
|
if is_valid_dune t then
|
||
|
t
|
||
|
else
|
||
|
invalid_argf "Jbuild atom '%s' is not a valid dune atom" t
|
||
|
|
||
|
let of_int i = of_string_exn Dune (string_of_int i)
|
||
|
let of_float x = of_string_exn Dune (string_of_float x)
|
||
|
let of_bool x = of_string_exn Dune (string_of_bool x)
|
||
|
let of_int64 i = of_string_exn Dune (Int64.to_string i)
|
||
|
let of_digest d = of_string_exn Dune (Digest.to_hex d)
|