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 =
Codec.Map.(
map (fun name age -> { name; age })
|> mem "name" (fun p -> p.name) Codec.text
|> mem "age" (fun p -> p.age) Codec.int
|> seal)
(* Encode to CBOR bytes *)
let encoded = Cbor.to_string person_codec { name = "Alice"; age = 30 }
(* Decode from CBOR bytes *)
let () =
match Cbor.of_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 Cbor.of_reader 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 =
Codec.Variant.(variant [
case 0 Codec.float (fun r -> Circle r)
(function Circle r -> Some r | _ -> None);
case 1 (Codec.tuple2 Codec.float Codec.float) (fun (w, h) -> Rect (w, h))
(function Rect (w, h) -> Some (w, h) | _ -> None);
])
API Overview#
The combinator surface lives under Cbor.Codec, organized by RFC 8949 major
type:
- Major 0/1 — integers --
int,int32,int64,uint,uint32,uint64 - Major 2 — byte string --
bytes - Major 3 — text string --
text - Major 4 — array --
array,array_of,tuple2,tuple3,tuple4 - Major 5 — map --
assoc,text_map,int_map,Map(records by text key),Map_int(records by int key, COSE / CWT style) - Major 6 — tag --
tag,tag_opt - Major 7 — simple / float --
null,bool,float - Sum types --
Variant(tag-discriminated),Variant_key(singleton-map) - Transformations --
map,conv,const,nullable,option,number,fix - Queries --
mem,int_mem,nth
Top-level I/O lives in Cbor:
Cbor.of_string,Cbor.of_string_exn— decode from CBOR bytesCbor.to_string— encode to CBOR bytesCbor.of_reader,Cbor.to_writer— bytesrw streamingCbor.decode,Cbor.encode— bridges toValue.tCbor.update_mem,Cbor.delete_mem— patch operations on maps
References#
- RFC 8949 -- Concise Binary Object Representation (CBOR)
Licence#
ISC License. See LICENSE.md for details.