Module serialize

Source
Expand description

Serialization and deserialization for the nix remote protocol.

The protocol has two primitive types: integers and byte buffers. All integers are encoded in 64 bits (little endian). I haven’t seen signed integers appear in the protocol yet, but presumably they’re encoded in twos complement. Byte buffers are encoded as a length (64-bit integer), followed by the bytes in the buffer. If the length of the buffer is not a multiple of 8, it is zero-padded to a multiple of 8 bytes.

The Nix source parses the protocol imperatively, but there are some common patterns that we implement declaratively with the help of serde’s derive macros:

  • structs and tuples are serialized as the concatenation of their fields (Nix does this manually for each struct)
  • sequences (like Vecs) are serialized as a length followed by the concatenation of the elements (Nix has functions like readStrings for this).

So for example, the struct

pub struct BuildPathsWithResults {
    paths: Vec<ByteBuf>,
    build_mode: u64,
}

gets serde-derived serialization implementations that encode it as:

  • the number of paths (an int)
  • the paths concatenated together, each of which consists of
    • a length (an int)
    • a byte buffer of that length
  • the build mode (an int)

Nix also has some sort of implicit “tagged union”, consisting of a type tag (and integer) followed by a body. This serializer does not have built-in support for that, because serde enums are built on string-valued tags (whereas the nix protocol wants integer tags). Instead, we have a separate tagged_serde macro for transforming enums into tuples.

Structs§

NixDeserializer
A deserializer for the nix remote protocol.
NixSerializer
A serializer for the nix remote protocol.
Tee

Enums§

Error

Traits§

NixReadExt
NixWriteExt

Type Aliases§

Result