Native CBOR codec with type-safe combinators
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

OCaml 98.5%
Dune 0.4%
Other 1.2%
18 1 0

Clone this repository

https://tangled.org/gazagnaire.org/ocaml-cbor https://tangled.org/did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-cbor
git@git.recoil.org:gazagnaire.org/ocaml-cbor git@git.recoil.org:did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-cbor

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

cbor#

Type-safe CBOR codec combinators for OCaml, with GADT-based bidirectional maps and bytesrw streaming.

Overview#

cbor provides encoding and decoding of CBOR (RFC 8949) using a combinator-based approach inspired by Jsont. Define a codec once as a value of type 'a t and use it for both directions. Codecs compose from base types through objects, arrays, variants, tags, and recursive types.

Streaming I/O is built on bytesrw for zero-copy reading and writing. Path-aware error messages pinpoint decode failures (e.g., $.items[3].name: expected string, got integer).

Installation#

Install with opam:

$ opam install nox-cbor

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-cbor

Usage#

open Cbor

(* Define a codec for a record type *)
type person = { name : string; age : int }

let person_codec =
  let open Obj in
  seal
    (let* name = mem "name" (fun p -> p.name) string in
     let* age = mem "age" (fun p -> p.age) int in
     return { name; age })

(* Encode to CBOR bytes *)
let encoded = encode_string person_codec { name = "Alice"; age = 30 }

(* Decode from CBOR bytes *)
let () =
  match decode_string person_codec encoded with
  | Ok p -> Printf.printf "%s is %d\n" p.name p.age
  | Error e -> prerr_endline (Error.to_string e)

(* Streaming decode from a bytesrw reader *)
let stream_decode encoded =
  let reader = Bytesrw.Bytes.Reader.of_string encoded in
  match decode person_codec reader with
  | Ok p -> Printf.printf "%s\n" p.name
  | Error e -> prerr_endline (Error.to_string e)

Variants and Tags#

open Cbor

type shape = Circle of float | Rect of float * float

let shape_codec =
  Variant.(variant [
    case 0 float (fun r -> Circle r)
      (function Circle r -> Some r | _ -> None);
    case 1 (tuple2 float float) (fun (w, h) -> Rect (w, h))
      (function Rect (w, h) -> Some (w, h) | _ -> None);
  ])

API Overview#

  • Base codecs -- null, bool, int, int32, int64, float, string, bytes, any
  • nullable, option -- Optional values
  • array, array_of, tuple2--tuple4 -- Array codecs
  • assoc, string_map, int_map -- Map codecs
  • Obj module -- Record builder with string keys: mem, mem_opt, mem_default, return, seal
  • Obj_int module -- Record builder with integer keys (COSE/CWT style)
  • Variant, Variant_key -- Sum types via CBOR tags or string-keyed maps
  • tag, tag_opt -- CBOR semantic tags
  • map, conv, const, fix -- Transformations and recursion
  • mem, int_mem, nth -- Query combinators
  • decode, decode_string -- Decoding (streaming and string)
  • encode, encode_string -- Encoding (streaming and string)

References#

  • RFC 8949 -- Concise Binary Object Representation (CBOR)

Licence#

ISC License. See LICENSE.md for details.