diff options
| author | Β·ππ΄πππ©π€ | 2025-12-11 20:58:19 +0000 |
|---|---|---|
| committer | Β·ππ΄πππ©π€ | 2025-12-11 20:58:19 +0000 |
| commit | 0ba222850396361e7a339811cd85abf33ea3e165 (patch) | |
| tree | 1d0088ccd4d7e16869a9482941c1249def6a8b5d /lib/kdl_lens_result.ml | |
| parent | 0d7fa712f20bc02d20153e78704f59c89f8a5361 (diff) | |
| download | nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.tar nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.tar.gz nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.tar.bz2 nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.tar.lz nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.tar.xz nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.tar.zst nixtaml-0ba222850396361e7a339811cd85abf33ea3e165.zip | |
make KDL module + fix casing
Diffstat (limited to 'lib/kdl_lens_result.ml')
| -rw-r--r-- | lib/kdl_lens_result.ml | 388 |
1 files changed, 0 insertions, 388 deletions
diff --git a/lib/kdl_lens_result.ml b/lib/kdl_lens_result.ml deleted file mode 100644 index 9ead98e..0000000 --- a/lib/kdl_lens_result.ml +++ /dev/null @@ -1,388 +0,0 @@ -(*ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -β SPDX-FileCopyrightText: eilveli β -β SPDX-FileContributor: toastal <toastal@posteo.net β -β SPDX-License-Identifier: MPL-2.0 β -β β -β Upstream: https://github.com/eilvelia/ocaml-kdl β -β Purpose: address βnote: we can possibly replace option with result for more β -β detailed errorsβ β -β β -β Short-comings: no βtrailβ for the errors & not extensible with user-defined β -β errors with ('a, 'b, 'err) proving difficult to work with β -ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ*) - -type lerr = [ - | `Cannot_each - | `Cannot_replace - | `Missing_annot - | `Missing_index of int - | `Missing_prop of string - | `Missing_top - | `Not_found of string * string option - | `Mismatched_type - | `Wrong_type_bool - | `Wrong_type_float - | `Wrong_type_Int - | `Wrong_type_Int32 - | `Wrong_type_Int64 - | `Wrong_type_native_int - | `Wrong_type_null - | `Wrong_type_number - | `Wrong_type_string - | `Wrong_type_stringNumber -] -[@@deriving show] - -let pp_lerr fmt = function - | `Cannot_each -> Fmt.pf fmt "Cannot each" - | `Cannot_replace -> Fmt.pf fmt "Cannot replace" - | `Missing_annot -> Fmt.pf fmt "Missing annotation" - | `Missing_prop prop -> Fmt.pf fmt "Missing property β%sβ" prop - | `Missing_index idx -> Fmt.pf fmt "Missing index β%dβ" idx - | `Missing_top -> Fmt.pf fmt "Missing top-level node" - | `Not_found (name, annot) -> - begin - match annot with - | None -> Fmt.pf fmt "Not found β%sβ" name - | Some a -> Fmt.pf fmt "Not found β%sβ with annotation (%s)" name a - end - | `Mismatched_type -> Fmt.pf fmt "Mismatched type" - | `Wrong_type_bool -> Fmt.pf fmt "Wrong type, expected a boolean" - | `Wrong_type_float -> Fmt.pf fmt "Wrong type, expected a float" - | `Wrong_type_Int -> Fmt.pf fmt "Wrong type, expected an int" - | `Wrong_type_Int32 -> Fmt.pf fmt "Wrong type, expected an int32" - | `Wrong_type_Int64 -> Fmt.pf fmt "Wrong type, expected an int64" - | `Wrong_type_native_int -> Fmt.pf fmt "Wrong type, expected a native int" - | `Wrong_type_null -> Fmt.pf fmt "Wrong type, expected a null" - | `Wrong_type_number -> Fmt.pf fmt "Wrong type, expected a number" - | `Wrong_type_string -> Fmt.pf fmt "Wrong type, expected a string" - | `Wrong_type_stringNumber -> Fmt.pf fmt "Wrong type, expected a string number" - -open Kdl - -(* note: we can possibly replace option with result for more detailed errors *) - -type ('s, 'a) lens = { - get: 's -> ('a, lerr) result; - set: 'a -> 's -> ('s, lerr) result; -} - -let get a lens = lens.get a - -let set a v lens = lens.set v a - -let get_exn a lens = - match lens.get a with - | Ok v -> v - (*| Error e -> failwith (String.concat "; " (List.map lerr_to_string e))*) - | Error e -> failwith (show_lerr e) - -let set_exn a v lens = - match lens.set v a with - | Ok v -> v - (*| Error e -> failwith (String.concat "; " (List.map lerr_to_string e))*) - | Error e -> failwith (show_lerr e) - -(* note: update can possibly be added to the definition of [lens] to increase - performance with more specialized implementations *) - -let update f a lens = - match lens.get a with - | Error e -> Error e - | Ok value -> - match f value with - | Ok value' -> lens.set value' a - | Error e -> Error e - -let compose l1 l2 = { - get = (fun x -> - match l2.get x with - | Ok x' -> l1.get x' - | Error e -> Error e - ); - set = (fun v a -> update (l1.set v) a l2) -} - -let ( // ) l1 l2 = compose l2 l1 - -let (|--) = ( // ) - -let (.@()) = get -let (.@() <-) a l v = set a v l - -let (.@!()) = get_exn -let (.@!() <-) a l v = set_exn a v l - -let node_name = { - get = (fun node -> Ok node.name); - set = (fun name node -> Ok {node with name}); -} - -let node_annot = { - get = (fun node -> Option.to_result ~none: `Missing_annot node.annot); - set = (fun annot node -> Ok {node with annot = Some annot}); -} - -(* Unset the annotation by passing None *) -let node_annot_opt = { - get = (fun node -> Ok node.annot); - set = (fun annot node -> Ok {node with annot}); -} - -let args = { - get = (fun node -> Ok node.args); - set = (fun args node -> Ok {node with args}); -} - -let props = { - get = (fun node -> Ok node.props); - set = (fun props node -> Ok {node with props}); -} - -let children = { - get = (fun node -> Ok node.children); - set = (fun children node -> Ok {node with children}); -} - -let top = { - get = (function node :: _ -> Ok node | [] -> Error `Missing_top); - set = (fun node -> function _ :: xs -> Ok (node :: xs) | [] -> Error `Missing_top); -} - -open struct - let nth_and_replace n x' list = - let found = ref false in - (* Note: Unlike List.mapi, this stops iterating when we've found the element *) - let [@tail_mod_cons] rec go i = function - | [] -> [] - | _ :: xs when i = n -> found := true; x' :: xs - | x :: xs -> x :: go (i + 1) xs - in - let result = go 0 list in - if !found then Ok result else Error (`Missing_index n) - - let filter_and_replace f replace_list list = - let found = ref false in - let f (replace, result) x = - if f x then - begin - found := true; - match replace with - | x' :: xs -> xs, x' :: result - | [] -> [], x :: result - end - else - replace, x :: result - in - let _, list = List.fold_left f (replace_list, []) list in - if !found then Ok (List.rev list) else Error `Cannot_replace - - let [@inline]matches_node ?annot name node = - String.equal node.name name - && ( - match annot with - | Some a -> - ( - match node.annot with - | Some a' -> String.equal a a' - | None -> false - ) - | None -> true - ) - - let rec find_node n annot name = function - | [] -> Error (`Not_found (name, annot)) - | x :: xs when matches_node ?annot name x -> - if n <= 0 then Ok x else find_node (n - 1) annot name xs - | _ :: xs -> find_node n annot name xs - - let find_and_replace_node nth annot name x' list = - let found = ref false in - let [@tail_mod_cons] rec go n = function - | [] -> [] - | x :: xs when matches_node ?annot name x -> - if n <= 0 then (found := true; x' :: xs) else x :: go (n - 1) xs - | x :: xs -> x :: go n xs - in - let result = go nth list in - if !found then Ok result else Error (`Not_found (name, annot)) -end - -let nth n = { - get = (fun list -> - List.nth_opt list n - |> Option.to_result ~none: (`Missing_index n) - ); - set = (fun x' list -> nth_and_replace n x' list) -} - -(* these operations are O(n), and update is quite inefficient *) -let arg n = { - (* Inlined [nth] instead of [args // nth n] *) - get = (fun node -> - List.nth_opt node.args n - |> Option.to_result ~none: (`Missing_index n) - ); - set = (fun arg' node -> - nth_and_replace n arg' node.args - |> Result.map (fun args -> {node with args}) - ) -} - -let first_arg = arg 0 - -let prop key = { - get = (fun node -> - List.assoc_opt key node.props - |> Option.to_result ~none: (`Missing_prop key) - ); - set = (fun v' node -> - let found = ref false in - let f (k, v) = if k = key then (found := true; k, v') else k, v in - let props = List.map f node.props in - if !found then Ok {node with props} else Error (`Missing_prop key) - ) -} - -let node ?(nth = 0) ?annot (name : string) = { - get = (fun nodes -> find_node nth annot name nodes); - set = (fun node' nodes -> find_and_replace_node nth annot name node' nodes) -} - -let node_many ?annot (name : string) = - let matches = matches_node ?annot name in - { - get = (fun nodes -> - match List.filter matches nodes with - | [] -> Error (`Not_found (name, annot)) - | xs -> Ok xs - ); - set = (fun nodes' nodes -> filter_and_replace matches nodes' nodes) - } - -let node_nth : int -> (node list, node) lens = nth - -(* TODO: get node by annot only? *) - -let child ?nth ?annot name = children // node ?nth ?annot name -let child_many ?annot name = children // node_many ?annot name -let child_nth n = children // node_nth n - -let value : (annot_value, value) lens = { - get = (fun (_, v) -> Ok v); - set = (fun v' (a, _) -> Ok (a, v')); -} - -let annot : (annot_value, string) lens = { - get = (fun (a, _) -> Option.to_result ~none: `Missing_annot a); - set = (fun a' (_, v) -> Ok (Some a', v)); -} - -let annot_opt : (annot_value, string option) lens = { - get = (fun (a, _) -> Ok a); - set = (fun a' (_, v) -> Ok (a', v)); -} - -let string = { - get = (function `String str -> Ok str | _ -> Error `Wrong_type_string); - set = (fun value' _value -> Ok (`String value')); -} - -(* Ast.Num.of_string not exposed *) -let number : (value, number) lens = { - get = (fun n -> L.number.get n |> Option.to_result ~none: `Wrong_type_number); - set = (fun num n -> L.number.set num n |> Option.to_result ~none: `Wrong_type_number); -} - -let string_number : (value, string) lens = { - get = (fun n -> L.string_number.get n |> Option.to_result ~none: `Wrong_type_stringNumber); - set = (fun x n -> L.string_number.set x n |> Option.to_result ~none: `Wrong_type_stringNumber); -} - -let float_number : (value, float) lens = { - get = (fun n -> L.float_number.get n |> Option.to_result ~none: `Wrong_type_float); - set = (fun x n -> L.float_number.set x n |> Option.to_result ~none: `Wrong_type_float); -} - -let int_number : (value, int) lens = { - get = (fun n -> L.int_number.get n |> Option.to_result ~none: `Wrong_type_Int); - set = (fun x n -> L.int_number.set x n |> Option.to_result ~none: `Wrong_type_Int); -} - -let int32_number : (value, int32) lens = { - get = (fun n -> L.int32_number.get n |> Option.to_result ~none: `Wrong_type_Int32); - set = (fun x n -> L.int32_number.set x n |> Option.to_result ~none: `Wrong_type_Int32); -} - -let int64_number : (value, int64) lens = { - get = (fun n -> L.int64_number.get n |> Option.to_result ~none: `Wrong_type_Int64); - set = (fun x n -> L.int64_number.set x n |> Option.to_result ~none: `Wrong_type_Int64); -} - -let nativeint_number : (value, nativeint) lens = { - get = (fun n -> L.nativeint_number.get n |> Option.to_result ~none: `Wrong_type_native_int); - set = (fun x n -> L.nativeint_number.set x n |> Option.to_result ~none: `Wrong_type_native_int); -} - -let bool = { - get = (function `Bool b -> Ok b | _ -> Error `Wrong_type_bool); - set = (fun value' _value -> Ok (`Bool value')) -} - -let null = { - get = (function `Null -> Ok () | _ -> Error `Wrong_type_null); - set = (fun _ _ -> Ok `Null) -} - -let string_value : (annot_value, string) lens = value // string -let number_value : (annot_value, number) lens = value // number -let string_number_value : (annot_value, string) lens = value // string_number -let float_number_value : (annot_value, float) lens = value // float_number -let int_number_value : (annot_value, int) lens = value // int_number -let int32_number_value : (annot_value, int32) lens = value // int32_number -let int64_number_value : (annot_value, int64) lens = value // int64_number -let nativeint_number_value : (annot_value, nativeint) lens = - value // nativeint_number -let bool_value : (annot_value, bool) lens = value // bool -let null_value : (annot_value, unit) lens = value // null - -let filter f = { - get = (fun list -> Ok (List.filter f list)); - set = (fun replace list -> filter_and_replace f replace list) -} - -open struct - exception Short_circuit - - let mapm_option f list = - let g a = - match f a with - | Ok x -> x - | Error _ -> raise_notrace Short_circuit - in - try - Ok (List.map g list) - with - | Short_circuit -> Error `Cannot_each -end - -let each l = { - get = (fun list -> mapm_option l.get list); - set = (fun replace_list list -> - let f (replace, result) v = - match replace with - | v' :: replace_rest -> - ( - match l.set v' v with - | Ok x -> replace_rest, x :: result - | Error _ -> raise_notrace Short_circuit - ) - | [] -> [], v :: result - in - try - let _, list = List.fold_left f (replace_list, []) list in - Ok (List.rev list) - with - | Short_circuit -> Error `Cannot_each - ) -} |
