B00_serialk_sexp.Sexpq
S-expression queries.
type path = (Sexp.index * Sexp.loc) list
The type for result paths. This is a sequence of indexing operations tupled with the source text location of the indexed s-expression in reverse order.
pp_path ~pp_loc ~pp_key ()
formats paths using pp_loc
(defaults to Sexp.pp_loc
) and pp_key
to format the keys (defaults to Sexp.pp_key
).
type error_kind = [
| `Key_unbound of string * string list |
| `Msg of string |
| `Nth_unbound of int * int |
| `Out_of_dom of string * string * string list |
]
The type for kinds of errors.
`Key_unbound (k, dom)
on k
that should have been in dom
(if not empty).`Msg m
an arbitrary message m
(should not include position information).`Nth_unbound (n, len)
on n
an out of bound index in a list of length len
.`Out_of_dom (kind, v, dom)
on v
of kind kind
that should have been in dom
val pp_error_kind : ?pp_em:string Sexp.fmt -> ?pp_key:string Sexp.fmt -> unit -> error_kind Sexp.fmt
pp_error_kind ~pp_loc ~pp_em ~pp_key ()
formats error kinds using pp_loc
for locations, pp_em
for emphasis and pp_key
for keys.
type error = error_kind * (path * Sexp.loc)
The type for query errors. The error kind tupled with the path to the offending s-expression and the location of the s-expression.
val pp_error : ?pp_loc:Sexp.loc Sexp.fmt -> ?pp_path:path Sexp.fmt -> ?pp_error_kind:error_kind Sexp.fmt -> ?pp_prefix:unit Sexp.fmt ->
unit -> error Sexp.fmt
pp_error ~pp_loc ~pp_path ~pp_error_kind ~pp_prefix ()
formats errors using pp_loc
, pp_path
(defaults to pp_path
), pp_error_kind
(defaults to pp_error_kind
) and pp_prefix
(defaults formats "Error: "
).
error_to_string ~pp_error r
converts an error in r
to a string using pp_error
, defaults to pp_error
.
The type for s-expression queries. A query either succeeds against an s-expression with a value of type 'a
or it fails.
query q s
is Ok v
if the query q
succeeds on s
and Error e
otherwise.
query_at_path q (s, p)
is like query
except it assumes s
is at path p
. Use to further query s-expressions obtained with sexp_with_path
so that errors return the full path to errors.
query' q s
is like query
except the result is composed with error_to_string
.
val succeed : 'a -> 'a t
succeed v
is a query that succeeds with value v
on any s-expression.
val fail : error_kind -> 'a t
fail k
is a query that fails on any s-expression with error kind k
.
val failf : ('a, Format.formatter, unit, 'b t) format4 -> 'a
failf fmt ...
is fail (`Msg m)
with m
formatted according to fmt
.
app fq q
queries an s-expression first with fq
and then with q
and applies the result of latter to the former.
pair q0 q1
queries an s-expression first with q0
and then with q1
and returns the pair of their result.
bind q f
queries an s-expression with q
, applies the result to f
and re-queries the s-expression with the result.
loc q
queries with q
an returns the result with the query path and source text location to the queried s-expression.
Queries for s-expressions. These queries never fail.
fold ~atom ~list
queries atoms with atom
and lists with list
.
sexp_with_path
is like sexp
but also returns the path toy s-expression.
Queries for atoms. These queries fail on lists.
val atom : string t
atom
queries an atom as a string.
atom_to ~kind p
queries an atom and parses it with p
. In case of Error m
fails with message m
. kind
is the kind of value parsed, used for the error in case a list is found.
TODO. Maybe combinators to devise an approriate parse function for atom_to
are a better idea than the following two combinators.
val enum : kind:string -> Set.Make(String).t -> string t
enum ~kind ss
queries an atom for one of the element of ss
and fails otherwise. kind
is for the kind of elements in ss
, it used for error reporting.
val enum_map : kind:string -> 'a Map.Make(String).t -> 'a t
enum_map ~pp_elt ~kind sm
queries an atom for it's map in sm
and fails if the atom is not bound in sm
. kind
is for the kind of elements in sm
, it used for error reporting.
val bool : bool t
bool
queries an atom for one of true
or false
.
val int : int t
int
queries an atom for an integer value parsed with int_of_string
.
val int32 : int32 t
int32
queries an atom for an integer value parsed with Int32
.of_string.
val int64 : int64 t
int64
queries an atom for an integer value parsed with Int64
.of_string.
val float : float t
float
queries an atom for a float value parsed with float_of_string
.
Queries for s-expression lists. These queries fail on atoms.
val is_empty : bool t
is_empty
queries a list for emptyness.
fold_list f q acc
queries the elements of a list from left to right with q
and folds the result with f
starting with acc
.
nth ?absent n q
queries the n
th index of a list with q
. If n
is negative counts from the end of the list, so -1
is the last list element. If the element does not exist this fails if absent
is None
and succeeds with v
if absent
is Some
v
.
delete_nth ~must_exist n
deletes the n
th element of the list. If the element does not exist this fails when must_exist
is true
or returns the list unchanged when must_exist
is false
.
Queries for s-expression dictionaries. These queries fail on atoms.
key ?absent k q
queries the value of key k
of a dictionary with q
. If k
is not bound this fails if absent
is None
and succeeds with v
if absent
is Some v
.
delete_key ~must_exist k
deletes key k
from the dictionary. If k
is not bound this fails when must_exist
is true
or returns the dictionary unchanged when must_exist
is false
.
val key_dom : validate:Set.Make(String).t option -> Set.Make(String).t t
key_dom validate
queries the key domain of a list of bindings. If validate
is Some dom
, the query fails if a key is not in dom
. The query also fails if a binding is not well-formed. pp_key
is used to format keys.
TODO. Not really happy about this function, we lose the key locations which is useful for further deconstruction. Also maybe we rather want binding folds.
atomic q
queries an atom or the atom of a singleton list with q
. It fails on empty lists or non-singleton lists.
This is useful for singleton dictionary bindings. In error reporting treats the list as if it doesn't exist syntactically which is the case in dictionary bindings.
val index : ?absent:'a -> Sexp.index -> 'a t -> 'a t
val delete_index : must_exist:bool -> Sexp.index -> Sexp.t t
delete_index ~must_exist i
deletes the s-expression index i
using delete_nth
or delete_key
according to i
.
These queries fail on indexing errors, that is if an atom gets indexed.
path p q
queries the s-expression found by p
using q
. If p
can't be found this fails if absent
is None
and succeeds with v
if absent
is Some v
.
probe_path p
is a query that probes for p
's existence. Except for indexing errors it always succeeds with (sp, s, rem)
:
p
is found, this is the path to sp
to the found expression s
and rem
is empty.p
is not found, this is the path sp
that leads to the s-expression s
that could not be indexed and rem
has the indexes that could not be performed.delete_at_path ~must_exist p
deletes the s-expression found by p
from the queried s-expression. If the path does not exist this fails if must_exist
is true
and returns the s-expression itself if must_exist
is false
.
splice_at_path ?stub ~must_exist p ~rep
replaces the s-expression found at p
by splicing rep
. If the path does not exist this fails if must_exist
is true
and the non-existing part of the path is created if must_exist
is false
. If elements need to be created stub
(defaults to Sexp.atom ""
) is used.
val splice_at_caret : ?stub:Sexp.t -> must_exist:bool -> Sexp.caret -> rep:Sexp.t -> Sexp.t t
splice_caret ?stub ~must_exist p rep
splices the s-expression rep
at the caret p
of the s-expression. If path of the caret does not exist this fails if must_exist
is true
and the non-existing part of the path is created if must_exist
is false
. If atoms need to be create stub
(defaults to Sexp.atom ""
) is used.
option q
queries with q
the value of an option represented according the encoding of Sexpg.option
.