package kdl

  1. Overview
  2. Docs

OCaml implementation of the KDL Document Language v2.

KDL is a data serialization format in the same vein as JSON, YAML, TOML, XML, SDLang, edn, and so on.

Small examples can be found in the README of the ocaml-kdl repository.

The definition of a KDL document

module Num : sig ... end

KDL numbers.

type number = Num.t

Alias of the Num.t polymorphic variant for convenience.

type value = [
  1. | `String of string
  2. | number
  3. | `Bool of bool
  4. | `Null
]

A KDL value: String, Number, Bool, Null.

type annot_value = string option * value

A KDL value with an optional type annotation. For example, (Some "u16", `Int 3201) is an annot_value.

type prop = string * annot_value

A KDL property is a key-value pair.

type node = {
  1. name : string;
  2. annot : string option;
  3. args : annot_value list;
  4. props : prop list;
  5. children : node list;
}

A KDL node. Nodes consist of the node name, optional type annotation, ordered arguments (values), unordered properties (a key-value map), and children nodes.

props is an association list; the order of the list is unspecified.

type t = node list

A KDL document is a list of nodes.

Parsing

type error_loc = Lexing.position * Lexing.position

The error location in bytes.

type error = string * error_loc

A parsing error: pair of the error message and error location.

val pp_error : Format.formatter -> error -> unit
exception Parse_error of error
val of_string : ?fname:string -> string -> (t, error) result

Parse KDL from a string. The string should be UTF8-encoded. ?fname is an optional filename that is used in locations.

val of_string_exn : ?fname:string -> string -> t

Raising version of of_string.

val of_channel : ?fname:string -> in_channel -> (t, error) result

Parse KDL from a channel.

val of_channel_exn : ?fname:string -> in_channel -> t

Raising version of of_channel.

val of_chunk_gen : ?fname:string -> (bytes -> offset:int -> len:int -> int) -> (t, error) result

of_chunk_gen ?fname f is an advanced function that parses KDL from byte chunks written by f. The function f is similar to input; f must write no more than ~len bytes at offset ~offset, returning the amount of written bytes. A return value of 0 means end of input. See also Lexing.from_function.

val of_chunk_gen_exn : ?fname:string -> (bytes -> offset:int -> len:int -> int) -> t

Raising version of of_chunk_gen.

Helpers

val node : ?annot:string -> string -> ?args:annot_value list -> ?props:prop list -> node list -> node

node ?annot name ?args ?props children constructs a node.

val arg : ?annot:string -> value -> annot_value

arg ?annot value constructs an argument (that is, a value with an optional type annotation).

val prop : ?annot:string -> string -> value -> prop

prop ?annot name value constructs a property.

Equivalence

val equal_value : value -> value -> bool
val equal_annot_value : annot_value -> annot_value -> bool
val equal_prop : prop -> prop -> bool
val equal_node : node -> node -> bool
val equal : t -> t -> bool

Sexp conversions

val sexp_of_value : [< value ] -> Sexplib0.Sexp.t
val sexp_of_annot_value : annot_value -> Sexplib0.Sexp.t
val sexp_of_prop : prop -> Sexplib0.Sexp.t
val sexp_of_node : node -> Sexplib0.Sexp.t
val sexp_of_t : t -> Sexplib0.Sexp.t

Pretty-printing

val indent : int ref

indent is the number of spaces used per indentation level. By default, indent is set to 2.

val pp_value : Format.formatter -> [< value ] -> unit

Pretty-print a value.

val pp_annot_value : Format.formatter -> annot_value -> unit

Pretty-print an annotated value.

val pp_prop : Format.formatter -> prop -> unit

Pretty-print a property.

val pp_node : Format.formatter -> node -> unit

Pretty-print a node using !indent as the indentation width for children nodes.

val pp_node_compact : Format.formatter -> node -> unit

Same as pp_node, but outputs the result in a single line.

val pp : Format.formatter -> t -> unit

Pretty-print a list of nodes or a KDL document using !indent as the indentation width for children nodes.

val pp_compact : Format.formatter -> t -> unit

Same as pp, but outputs the result in a single line.

val to_string : t -> string

Pretty-print a KDL document into a string using pp.

Type annotations

KDL defines reserved type annotations. Some of them are supported out of the box in ocaml-kdl. An annotated value can be "interpreted" using the interpret function. If the type annotation is unknown, `Other is returned.

typed_value can be extended with custom type annotations, for example, the following way:

type typed_value = [ Kdl.typed_value
                   | `Date of (* ... *) ]

let interpret : _ -> [> typed_value ] = function
  | Some "date", value -> `Date ((* ... parse ISO 8601 date ... *))
  | x -> Kdl.interpret x
type typed_value = [
  1. | `I8 of int
  2. | `I16 of int
  3. | `I32 of int32
  4. | `I64 of int64
  5. | `U8 of int
  6. | `U16 of int
  7. | `U32 of int32
  8. | `U64 of int64
  9. | `Isize of nativeint
  10. | `Usize of nativeint
  11. | `F32 of float
  12. | `F64 of float
  13. | `Base64 of bytes
  14. | `Other of string * value
  15. | `Unannotated of value
]
exception Invalid_annotation of string
val interpret : annot_value -> [> typed_value ]

Interpret a type-annotated value.

Note: f32 is currently the same as f64.

  • raises Invalid_annotation

    if the value is invalid. For example, if the value is annotated as "u8" but exceeds the range of u8, Invalid_annotation is raised.

val pp_typed_value : Format.formatter -> [< typed_value ] -> unit

Lenses

module L : sig ... end

Basic partial "lenses" for accessing deeply-nested KDL structures.

OCaml

Innovation. Community. Security.