MST.CAR (mst v0.1.0)

View Source

Bridges MST.Tree with the DASL CAR file format.

Provides functions to load an MST from a CAR binary or stream, and to export an MST back to CAR format. The CAR header's first root CID is treated as the MST root; any additional roots are ignored.

MST node blocks (DAG-CBOR codec, :drisl) are decoded into MST.Node structs and stored in an MST.Store.Memory. Non-MST blocks (e.g. record data with the :raw codec) are ignored during import — the store only holds MST structural nodes.

Example

{:ok, tree} = MST.CAR.from_binary(File.read!("repo.car"))
{:ok, pairs} = MST.Tree.to_list(tree)

Summary

Functions

Loads an MST from a CAR-encoded binary.

Loads an MST from an already-decoded DASL.CAR struct.

Loads an MST from a CAR stream (an Enumerable of binary chunks).

Serialises an MST.Tree to a CAR-encoded binary.

Returns a stream of DASL.CAR stream items for the tree in pre-order (root first, then depth-first left-to-right).

Types

car_error()

@type car_error() ::
  {:error, :header, atom()} | {:error, :block, atom()} | {:error, atom()}

Functions

from_binary(binary, opts \\ [])

@spec from_binary(
  binary(),
  keyword()
) :: {:ok, MST.Tree.t()} | car_error()

Loads an MST from a CAR-encoded binary.

Decodes all blocks, populates an MST.Store.Memory with MST nodes (DAG-CBOR codec), and returns an MST.Tree rooted at the CAR's first root CID.

Accepts the same options as DASL.CAR.decode/2 (verify: boolean).

Examples

iex> store = MST.Store.Memory.new()
iex> tree = MST.Tree.new(store)
iex> val = DASL.CID.compute("data")
iex> {:ok, tree} = MST.Tree.put(tree, "col/key", val)
iex> {:ok, binary} = MST.CAR.to_binary(tree)
iex> {:ok, tree2} = MST.CAR.from_binary(binary)
iex> MST.Tree.get(tree2, "col/key")
{:ok, val}

from_car(car)

@spec from_car(DASL.CAR.t()) :: {:ok, MST.Tree.t()} | car_error()

Loads an MST from an already-decoded DASL.CAR struct.

Populates an MST.Store.Memory from the struct's blocks map and returns an MST.Tree rooted at the CAR's first root CID. Use this when you already hold a %DASL.CAR{} in memory and want to avoid a redundant encode/decode cycle.

Examples

iex> store = MST.Store.Memory.new()
iex> tree = MST.Tree.new(store)
iex> val = DASL.CID.compute("data")
iex> {:ok, tree} = MST.Tree.put(tree, "col/key", val)
iex> {:ok, binary} = MST.CAR.to_binary(tree)
iex> {:ok, car} = DASL.CAR.decode(binary)
iex> {:ok, tree2} = MST.CAR.from_car(car)
iex> MST.Tree.get(tree2, "col/key")
{:ok, val}

from_stream(stream, opts \\ [])

@spec from_stream(
  Enumerable.t(),
  keyword()
) :: {:ok, MST.Tree.t()} | car_error()

Loads an MST from a CAR stream (an Enumerable of binary chunks).

Streams blocks through DASL.CAR.stream_decode/2, populating an MST.Store.Memory incrementally. Useful for large files where you want to avoid loading the full binary into memory at once. Converts stream raises to error tuples.

Options

  • :verify — verify CID digests of incoming blocks (default: true)

Examples

iex> store = MST.Store.Memory.new()
iex> tree = MST.Tree.new(store)
iex> val = DASL.CID.compute("data")
iex> {:ok, tree} = MST.Tree.put(tree, "col/key", val)
iex> {:ok, binary} = MST.CAR.to_binary(tree)
iex> chunk_stream = [binary]
iex> {:ok, tree2} = MST.CAR.from_stream(chunk_stream)
iex> MST.Tree.get(tree2, "col/key")
{:ok, val}

to_binary(tree)

@spec to_binary(MST.Tree.t()) :: {:ok, binary()} | car_error()

Serialises an MST.Tree to a CAR-encoded binary.

Collects all reachable MST node blocks and wraps them in a CARv1 file with the tree root as the sole header root.

Examples

iex> store = MST.Store.Memory.new()
iex> tree = MST.Tree.new(store)
iex> val = DASL.CID.compute("data")
iex> {:ok, tree} = MST.Tree.put(tree, "col/key", val)
iex> {:ok, binary} = MST.CAR.to_binary(tree)
iex> is_binary(binary)
true

to_stream(tree)

@spec to_stream(MST.Tree.t()) :: Enumerable.t()

Returns a stream of DASL.CAR stream items for the tree in pre-order (root first, then depth-first left-to-right).

Emits {:header, 1, [root_cid]} followed by {:block, cid, bytes} for each reachable MST node.

This stream can be piped into a custom CAR writer. It does not produce a fully-encoded CAR binary — use to_binary/2 for that.