vif/lib/modname.ml

38 lines
1.1 KiB
OCaml
Raw Normal View History

2024-12-30 12:41:55 +00:00
type t = string
let msgf fmt = Format.kasprintf (fun msg -> `Msg msg) fmt
let for_all f str =
let rec go acc idx =
if idx < String.length str then go (f str.[idx] && acc) (succ idx) else acc
in
go true 0
let is_upper = function 'A' .. 'Z' -> true | _ -> false
let is_lower = function 'a' .. 'z' -> true | _ -> false
let is_valid_module_char = function
| 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '\'' -> true
| '-' ->
true
(* XXX(dinosaure): an example exists: [First-class-modules].
[ocamlopt] can compile it but it emits an warning. *)
| _ -> false
let of_string str =
if String.length str < 1 then Error (msgf "Invalid empty module name")
else if
(is_upper str.[0] || is_lower str.[0]) && for_all is_valid_module_char str
then Ok str
else Error (msgf "Invalid module name: %S" str)
let v str =
match of_string str with Ok v -> v | Error (`Msg err) -> failwith err
let pp ppf t = Format.pp_print_string ppf t
let reflect ppf t = Fmt.pf ppf "(Modname.v %S)" t
let to_string v = v
let compare = String.compare
module Map = Map.Make (String)