Liking cljdoc? Tell your friends :D

Types

Naive Fressian Types

Typerustcljsclj
NULL()/Nonenilnil
TRUE/FALSEboolboolbool
INTi64NumberLong
FLOATf32NumberFloat
DOUBLEf64NumberDouble
BYTESserde_bytes::ByteBuf 0Int8Arraybyte[]
STRINGstringstringstring
UTF81stringstringstring
LISTVec<T>vecvec
MAPmapmapmap
SETtypes::SET0setset
SYMtypes::SYM2symsym
KEYtypes::KEY2kwkw
INSTtypes::INST3#inst#inst
UUIDtypes::UUID3#UUID#UUID
REGEXtypes::REGEX3regexregex
URItypes::URI3goog.UriURL
INT_ARRAYtypes::IntArray(Vec<i32>)0Int32Arrayint[]
LONG_ARRAYtypes::LongArray(Vec<i64>)0Array<Number>4long[]
FLOAT_ARRAYtypes::FloatArray(Vec<f32>)0Float32Arrayfloat[]
DOUBLE_ARRAYtypes::DoubleArray(Vec<f64>)0Float64Arraydouble[]
BOOLEAN_ARRAYtypes::BooleanArray(Vec<bool>)0Array<bool>bool[]

Unsupported Fressian Types (WIP)

Typerustcljsclj
BIGINT??????BigInt
BIGDEC??????BigDec
Records???5records/TaggedObjectsrecords/TaggedObjects
CHAR6char (utf8)stringjava char
OBJECT_ARRAY???Obj[]Obj[]

Basic Rust (Serde) Types

SerdeFressiancljsclj
unitNULLnilnil
boolT/Fboolbool
i8INTnumberlong
i16INTnumberlong
i32INTnumberlong
i64INTnumber4long
u8INTnumberlong
u16INTnumberlong
u32INTnumberlong
u644INTnumbernumber
f32FLOATnumberfloat
f64DOUBLEnumberdouble
char6stringstringchar
stringSTRINGstringstring
\-->UTF81stringtag -> string
[u8]BYTESbyte-arraybyte-array
Optionvalue/NILvalue/NILvalue/NIL
tupleLISTvecvec

Collections

SerdeFressiancljsclj
seqLISTvecvec
mapMAPmapmap

Structs and Enums (WIP)

It makes sense to serialize structs and enum variants as fressian TaggedObjects ie records or proper types. To pull this off, serde-fressian needs better support for caching. In order to better support caching, I'd like to land on a good pattern for serializing string pointers so that js interop is truly zero-copy where possible. So there are still yaks to shave.

Currently enums just serialize to the variant's value, structs serialize as maps, tuples to seqs (LIST). This is lossy, for both structs and enums because the type's name and some type information is lost. Serde offers custom attributes for altering this behavior, but right now serde-fressian mostly ignores names.

Structs
SerdeFressianclj(s)Example
unit_structNULLnilFoo;
newtype_variantTTFoo(T)
tuple_structLISTvecPoint(x,y,z)
structMAPmap{"foo": T}
Enums
SerdeFressianclj(s)Example
unit_variantstringstringFoo::Bar;
newtype_variantTTFoo::Baz(T)
tuple_variantLISTvecFoo::Point(x,y,z)
struct_variantMAPmapFoo::StructVar({"foo": T})

Unsupported Rust Types

SerdeFressiancljsclj
i128BIGINTTODObigint
u128BIGINTTODObigint

complications

All standard rust types have built-in Serialize/Deserialize impls which prevent fine grain control over serialization. For example, HashSets, BTreeSets, Slices, and Vec are all written as generic sequences and the nuance of each container is lost. This is a known source of friction in serde, and in the future there will be a way to override Serialization impls. Until then, the workaround solution is to create a 'newtype' struct enclosing your target type, which allows you to use custom serialize impls. You can use wrapper types directly, or use serde attributes (see below). This doesn't cost anything, it is just an annoyance.

The most common wrapper you'll probably need is the ByteBuf provided by the serde_bytes crate. This let's you write Vec<u8> and &[u8] as BYTE arrays rather than generic lists.

use serde_bytes::{ByteBuf};
use serde_fressian::ser;

let bytes: Vec<u8> = vec![0,1,2];
let output = ser::to_vec(&bytes).unwrap(); //--> serialized as LIST

let bb = serde_bytes::ByteBuf::from(bytes);
let output = ser::to_vec(&bb).unwrap(); //--> serialized as BYTES

serde_fressian::set

This module provides the set::SET wrapper for BTreeSets and set::HASHSET for HashSets. serde_fressian prefers BTreeSets over HashSets because the former implements Hash on the Set container itself. The same is true for BtreeMaps vs HashMaps. Hashing the container itself is required for implementing serde_fressian::value (see below) because it enables using the containers themselves as keys (..or set values), which may show up in that crazy clojure data.

#[macro_use]
extern crate maplit; // provides map & set literals
use std::collections::{BTreeSet,HashSet};
use serde_fressian::set::{SET, HASHSET};
use serde_fressian::ser;

let btreeset: BTreeSet<i64> = btreeset!{0,1,2,3};
let output = ser::to_vec(&btreeset); //--> serialized as LIST; [0 1 2 3]

let wrapped_btreeset: SET<i64> = SET::from(btreeset);
let output = ser::to_vec(&wrapped_btreeset); //--> serialized as SET; #{0 1 2 3}

// SET derives hash from its btreeset, so it can be stored in a hashset if we want
// but we could not do the other way around.
let hashset: HashSet<SET<i64>> = hashset!{wrapped_btreeset};
let output = ser::to_vec(&hashset); //--> serialized as LIST; [#{0 1 2 3}]

let wrapped_hashset: HASHSET<SET<i64>> = HASHSET::from(hashset);
let output = ser::to_vec(&wrapped_hashset); //--> serialized as SET; #{#{0 1 2 3}}

serde_fressian::typed_arrays

This module provides additional wrappers for fressian's typed arrays:

use serde_fressian::ser;
use serde_fressian::typed_arrays::{DoubleArray};

let v: Vec<f64> = vec![-2.0, -1.0, 0.0, 1.0, 2.0];
let output = ser::to_vec(&v).unwrap(); //--> serialized as LIST

let da: DoubleArray = DoubleArray::from_vec(v);
let output = ser::to_vec(&da).unwrap(); //--> serialized as DOUBLE_ARRAY

named-types

As you would expect, symbols and keywords do not have analogous rust types. The serde_fressian::sym::{SYM} and serde_fressian::key::{KEY} types are provided for compatibility. They are both tuple structs composed of an Option<String> namespace and a String Name. They have no other built-in functionality outside of lossless serialization.

optional-deps

With the expectation that they will be less commonly used, the remaining types default to newtypes over primitives in the interest of keeping binaries small. You can use compiler flags to enable extra functionality provided by external crates:

  • serde_fressian::regex::{REGEX}
    • by default is just a newtype around String
    • compile with the use_regex_crate feature to enable the external regex crate
  • serde_fressian::uri::{URI}
    • by default is just a newtype around String
    • compile with the use_url_crate feature to enable the external url crate
  • serde_fressian::uuid::{UUID}
    • by default is just a newtype around ByteBuf
    • compile with the use_uuid_crate feature to enable the external uuid crate
  • serde_fressian::inst::{INST}
    • by default is just a newtype around i64
    • TODO: support the chrono crate

raw-utf8

integer-safety

records

chars

Using Serde Attributes

You can use serde attributes to use custom serialize/deserialize impls produced by serde-derive. For example, this is from serde_bytes

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_bytes;

#[derive(Serialize)]
struct Efficient<'a> {
    #[serde(with = "serde_bytes")]
    bytes: &'a [u8],

    #[serde(with = "serde_bytes")]
    byte_buf: Vec<u8>,
}

#[derive(Serialize, Deserialize)]
struct Packet {
    #[serde(with = "serde_bytes")]
    payload: Vec<u8>,
}

serde_fressian::value::Value


Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close