loc#
Source locations and structured errors shared across text codecs (JSON, TOML, YAML, XML, CSV, S-expression, ...).
Every OCaml codec library needs the same plumbing: byte ranges, line
positions, context-aware error paths, and a printer that matches the
OCaml compiler / GNU error convention. loc provides that plumbing as
one small library so codecs depend on it instead of each reinventing
it — or, worse, exposing a private error type that upstream tools
cannot compose.
Provides:
Loc— byte and line ranges for UTF-8 source textLoc.Meta— node metadata: source location and surrounding whitespaceLoc.Path— structural paths (Mem of string node | Nth of int node)Loc.Context— navigation contexts accumulated during descentLoc.Error— structured errors with an extensible kind, source location, and contextual path; formatted per the OCaml compiler / GNU error conventionsexception Loc.Error of Loc.Error.t— single shared exception for cross-package error propagation
Installation#
Install with opam:
$ opam install nox-loc
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install nox-loc
Requires OCaml >= 4.14 and fmt.
Usage#
Raise a structured error at a specific source location:
let demo_raise () =
let loc =
Loc.make ~file:"config.toml"
~first_byte:42 ~last_byte:47
~first_line_num:3 ~first_line_byte:0
~last_line_num:3 ~last_line_byte:0
in
let meta = Loc.Meta.make loc in
try Loc.Error.failf meta "expected %s, got %s" "integer" "\"nope\""
with Loc.Error e -> print_endline (Loc.Error.to_string e)
Wrap a raised error with structural context as it bubbles up through nested object members:
let demo_push () =
let table = ("table [server]", Loc.Meta.none) in
try
try Loc.Error.fail Loc.Meta.none "not a number"
with Loc.Error e ->
Loc.Error.push_object table ("port", Loc.Meta.none) e
with Loc.Error e -> print_endline (Loc.Error.to_string e)
Extend the error kind for a domain-specific codec and register a printer:
type Loc.Error.kind += Unknown_key of string
let register () =
Loc.Error.register_kind_printer (function
| Unknown_key k -> Some (fun ppf -> Format.fprintf ppf "unknown key %S" k)
| _ -> None)
API#
See lib/loc.mli for the full signature.
Upstream#
- jsont — Daniel Bünzli's JSON codec library, of which this package is an extracted subset.
- jsont_base.ml
— source for
Loc,Meta,Path, and theFmthelper. - jsont.ml
— source for the
Errormodule (minus JSON-specific predefined errors).
License#
ISC, matching upstream. See LICENSE.md.