Documents

The example parses the people document in your selected format. It then reads Ada's age through the document nodes. Typed reads give you these values without serializing the document.

Example

Read Ada's age

people_text holds this document:

edn287 B
{:#_ada {:name "Ada"
         :role "engineer"
         :age  36}
 :#_bob {:name   "Bob"
         :role   "engineer"
         :age    41
         :mentor {:#link "#_ada"}}
 :#_cy  {:name "Cy"
         :role "designer"
         :age  29}
 :#_tx  {:author "smoke"
         :reason "seed"}}
c648 B
stardust_document *people = NULL;
uint32_t root = 0, ada = 0, age = 0;
int64_t result = 0;
uint32_t status = stardust_parse(people_text, STARDUST_EDN, &people);
if (status == STARDUST_OK) status = stardust_document_root(people, &root);
if (status == STARDUST_OK) status = stardust_document_member(people, root, (stardust_bytes){(const uint8_t *)"#_ada", 5}, &ada);
if (status == STARDUST_OK) status = stardust_document_member(people, ada, (stardust_bytes){(const uint8_t *)"age", 3}, &age);
if (status == STARDUST_OK) status = stardust_document_i64(people, age, &result);
stardust_document_release(people);
if (status != STARDUST_OK) return status;
Result / 11 B
{:value 36}

Numbers

A document number is an i64 integer or a finite f64 value. The number type defines both.

  • An integer read requires an integer node. A floating-point node can cause the read to fail.
  • Choose the typed read that matches the node that you read.

Operations

OperationReturnsSummary
stardust_parseStatus. document through outputparse(text, format) returns an owned document.
stardust_document_rootStatus. node through outputdocument.root() returns the root node ID.
stardust_document_countStatus. count through outputdocument.count() returns the number of nodes.
readUnavailabledocument.read(id) returns a node view: kind, boolean, parent, position, first_child, next_sibling, key and text.
stardust_document_read_manyStatus. node_views through outputdocument.read_many(start, capacity) reads consecutive node views.
stardust_document_memberStatus. node through outputdocument.member(id, key) returns the first matching object member ID.
childrenUnavailabledocument.children(id) iterates the node views of a node's children in order.
membersUnavailabledocument.members(id) iterates the members of an object node in order, each with its key.
stardust_document_i64Status. integer through outputRead an exact signed integer.
stardust_document_f64Status. real through outputRead a finite floating-point number.
stardust_document_releasevoidRelease the document handle.

stardust_parse

c92 B
uint32_t stardust_parse(stardust_bytes source, uint32_t format, stardust_document **output);
c97 B
uint32_t stardust_document_error(const stardust_document *doc, stardust_diagnostic_view *output);

Parameters

stardust_parse

ParameterTypeOwnershipDefaultMeaning
sourcestardust_bytesValueRequiredValue passed to the call.
formatuint32_tValueRequiredThe codec to use for this operation.
outputstardust_document **Owned outputRequiredReceives a library-owned handle. Release it after use.

stardust_document_error

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
outputstardust_diagnostic_view *Caller-owned outputRequiredReceives a record. Its pointer fields follow the record's ownership contract.

Errors

StatusWhen
STARDUST_INVALID_JSONJSON text is malformed
STARDUST_INVALID_ARGUMENTthe text is malformed, the format is unknown or a number is outside i64 or finite f64
STARDUST_OUT_OF_MEMORYnative memory is exhausted

Examples

Parse the shared DUST expression fixture

expression_text holds these bytes:

text278 B
// One expression built once and evaluated against several inputs. The
// evaluate examples load this file, build `expression`, evaluate it with each
// of `inputs` in order and compare each result with `expected`.
expression [+ ?x 1]
inputs     [{x 1} {x 41}]
expected   [2 42]
c187 B
stardust_document *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_DUST, &result);
if (status != STARDUST_OK) {stardust_document_release(result); return status;}
Result / 330 B
{:value {:$comment   "One expression built once and evaluated against several inputs. The\nevaluate examples load this file, build `expression`, evaluate it with each\nof `inputs` in order and compare each result with `expected`."
         :expression ["+" ?x 1]
         :inputs     [{:x 1} {:x 41}]
         :expected   [2 42]}}

Report a malformed byte at offset zero

malformed_text holds these bytes:

text1 B
]
c188 B
stardust_document *failed = NULL;
uint32_t status = stardust_parse(malformed_text, STARDUST_DUST, &failed);
stardust_diagnostic_view result = {0};
stardust_document_error(failed, &result);
Result / 204 B
{:value {:code    "invalid_dust"
         :message "Invalid_Syntax at offset 0"
         :path    nil
         :field   nil
         :entity  nil
         :offset  0
         :status  "invalid_argument"}}

Report malformed DUST

malformed_text holds these bytes:

text1 B
[
c188 B
stardust_document *failed = NULL;
uint32_t status = stardust_parse(malformed_text, STARDUST_DUST, &failed);
stardust_diagnostic_view result = {0};
stardust_document_error(failed, &result);
Result / 204 B
{:value {:code    "invalid_dust"
         :message "Unexpected_End at offset 2"
         :path    nil
         :field   nil
         :entity  nil
         :offset  2
         :status  "invalid_argument"}}

Also calls: stardust_document_error

stardust_document_root

c78 B
uint32_t stardust_document_root(const stardust_document *doc, uint32_t *node);

Parameters

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
nodeuint32_t *Caller-owned outputRequiredReceives the scalar result.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTa required input or output pointer is NULL, or an input owner is not ready

Examples

document/root

input_text holds this document:

edn7 B
{:x 41}
c296 B
stardust_document *source = NULL;
uint32_t root = 0;
uint32_t status = stardust_parse(input_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_root(source, &root);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
int64_t result = root;
Result / 10 B
{:value 0}

stardust_document_count

c79 B
uint32_t stardust_document_count(const stardust_document *doc, int64_t *count);

Parameters

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
countint64_t *Caller-owned outputRequiredReceives the scalar result.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTa required input or output pointer is NULL, or an input owner is not ready

Examples

document/count

input_text holds this document:

edn7 B
{:x 41}
c277 B
stardust_document *source = NULL;
int64_t result = 0;
uint32_t status = stardust_parse(input_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_count(source, &result);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
Result / 10 B
{:value 2}

read

Call stardust_document_read_many with capacity 1.

Also calls: stardust_document_read_many

stardust_document_read_many

c147 B
uint32_t stardust_document_read_many(const stardust_document *doc, uint32_t start, int64_t capacity, stardust_node_view *output, int64_t *written);

Parameters

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
startuint32_tValueRequiredThe first node ID of the consecutive read.
capacityint64_tValueRequiredThe maximum number of node views to read. For output slices, the call uses the caller's slice length.
outputstardust_node_view *Caller-owned arrayNULLWrites at most capacity elements and reports their count in written.
writtenint64_t *Caller-owned outputRequiredReceives the scalar result.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTstart is past the last node or capacity is negative

Examples

document/read_many

input_text holds this document:

edn7 B
{:x 41}
c526 B
stardust_document *source = NULL;
uint32_t root = 0;
stardust_node_view view = {0};
int64_t written = 0;
uint32_t status = stardust_parse(input_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_root(source, &root);
if (status == STARDUST_OK) status = stardust_document_read_many(source, root, 1, &view, &written);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
// The root object has no key or text, so the view borrows nothing.
stardust_node_view result = view;
Result / 218 B
{:value {:kind         "object"
         :boolean      false
         :parent       nil
         :position     0
         :first_child  1
         :next_sibling nil
         :key          ""
         :text         ""}}

document/read_many

input_text holds this document:

edn7 B
{:x 41}
c526 B
stardust_document *source = NULL;
uint32_t root = 0;
stardust_node_view view = {0};
int64_t written = 0;
uint32_t status = stardust_parse(input_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_root(source, &root);
if (status == STARDUST_OK) status = stardust_document_read_many(source, root, 1, &view, &written);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
// The root object has no key or text, so the view borrows nothing.
stardust_node_view result = view;
Result / 218 B
{:value {:kind         "object"
         :boolean      false
         :parent       nil
         :position     0
         :first_child  1
         :next_sibling nil
         :key          ""
         :text         ""}}

stardust_document_member

c118 B
uint32_t stardust_document_member(const stardust_document *doc, uint32_t object, stardust_bytes name, uint32_t *node);

Parameters

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
objectuint32_tValueRequiredValue passed to the call.
namestardust_bytesValueRequiredValue passed to the call.
nodeuint32_t *Caller-owned outputRequiredReceives the scalar result.

Errors

StatusWhen
STARDUST_NOT_FOUNDthe object has no member with the key
STARDUST_INVALID_ARGUMENTid is not an object node of the document

Examples

document/member

input_text holds this document:

edn7 B
{:x 41}
c432 B
stardust_document *source = NULL;
uint32_t root = 0, node = 0;
uint32_t status = stardust_parse(input_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_root(source, &root);
if (status == STARDUST_OK) status = stardust_document_member(source, root, (stardust_bytes){(const uint8_t *)"x", 1}, &node);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
int64_t result = node;
Result / 10 B
{:value 1}

children

Read the first child, then follow next_sibling with stardust_document_read_many.

Also calls: stardust_document_read_many

members

Follow the children of an object node; each node view carries its key.

Also calls: stardust_document_read_many

stardust_document_i64

c93 B
uint32_t stardust_document_i64(const stardust_document *doc, uint32_t node, int64_t *output);

Parameters

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
nodeuint32_tValueRequiredValue passed to the call.
outputint64_t *Caller-owned outputRequiredReceives the scalar result.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTthe node is not an integer number

Examples

document/i64

input_text holds this document:

edn7 B
{:x 41}
c511 B
stardust_document *source = NULL;
uint32_t root = 0, node = 0;
int64_t result = 0;
uint32_t status = stardust_parse(input_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_root(source, &root);
if (status == STARDUST_OK) status = stardust_document_member(source, root, (stardust_bytes){(const uint8_t *)"x", 1}, &node);
if (status == STARDUST_OK) status = stardust_document_i64(source, node, &result);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
Result / 11 B
{:value 41}

stardust_document_f64

c92 B
uint32_t stardust_document_f64(const stardust_document *doc, uint32_t node, double *output);

Parameters

ParameterTypeOwnershipDefaultMeaning
docconst stardust_document *Borrowed handleRequiredKeep the handle alive until the call returns.
nodeuint32_tValueRequiredValue passed to the call.
outputdouble *Caller-owned outputRequiredReceives the scalar result.

Errors

StatusWhen
STARDUST_INVALID_ARGUMENTthe node is not a number or its value overflows f64

Notes

Integer conversion can round values outside the exact f64 integer range.

Examples

document/f64

number_text holds this document:

edn3 B
1.0
c375 B
stardust_document *source = NULL;
uint32_t root = 0;
double result = 0;
uint32_t status = stardust_parse(number_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_document_root(source, &root);
if (status == STARDUST_OK) status = stardust_document_f64(source, root, &result);
stardust_document_release(source);
if (status != STARDUST_OK) return status;
Result / 12 B
{:value 1.0}

stardust_document_release

c55 B
void stardust_document_release(stardust_document *doc);

Consumes the receiver handle.

Parameters

ParameterTypeOwnershipDefaultMeaning
docstardust_document *Consumed handleNULLEnds ownership. Do not use the handle after this call.

Examples

document/close

expression_text holds this document:

edn10 B
["+" ?x 1]
c337 B
stardust_document *source = NULL;
stardust_text *result = NULL;
uint32_t status = stardust_parse(expression_text, STARDUST_EDN, &source);
if (status == STARDUST_OK) status = stardust_serialize(source, STARDUST_EDN, 0, &result);
stardust_document_release(source);
if (status != STARDUST_OK) {stardust_text_release(result); return status;}
Result / 31 B
{:value {:text "[\"+\" ?x 1]"}}

stardust_node_view

This record contains the result of read and read_many. The key and text fields borrow the document until it closes.

FieldC typeUnitRangeAbsentMeaning
kinduint32_tNoneUnsigned u32Always present—
booleanuint32_tNoneUnsigned u32Always presentTrue only for true.
parentuint32_tNoneUnsigned u32STARDUST_DOCUMENT_NO_NODESTARDUST_DOCUMENT_NO_NODE shows the root.
positionuint32_tCountUnsigned u32Always presentIndex within the parent container.
first_childuint32_tNoneUnsigned u32STARDUST_DOCUMENT_NO_NODESTARDUST_DOCUMENT_NO_NODE shows that there is no child.
next_siblinguint32_tNoneUnsigned u32STARDUST_DOCUMENT_NO_NODESTARDUST_DOCUMENT_NO_NODE shows that there is no next sibling.
keystardust_bytesNoneC type rangeAlways presentMember key of an object member, else empty.
textstardust_bytesNoneC type rangeAlways presentValue of a string, else empty. It can contain NUL.

stardust_node_input

This record supplies a node for add and add_many. The number field holds a typed i64 or f64 value. Go uses I64/F64, Rust and Odin use Number, Clojure uses long or double, and Python uses int or float. This value sets the ABI number kind and the integer or real field.

FieldC typeRangeDefaultAbsentMeaning
parentuint32_tUnsigned u32Required: node ID or STARDUST_DOCUMENT_NO_NODESTARDUST_DOCUMENT_NO_NODESTARDUST_DOCUMENT_NO_NODE adds the root.
kinduint32_tUnsigned u32ZeroAlways present—
booleanuint32_tUnsigned u32ZeroAlways presentValue of a boolean node.
numberuint32_tUnsigned u32STARDUST_NUMBER_INTEGER (0)Always presentSelects integer or real for a Number node. Zero selects Integer.
keystardust_bytesC type rangeZeroAlways presentMember key when the parent is an object.
textstardust_bytesC type rangeZeroAlways presentValue of a string node.
integerint64_tSigned i64ZeroAlways presentContains the value when number is STARDUST_NUMBER_INTEGER. Otherwise, set integer to zero.
realdoubleC type rangeZeroAlways presentContains the finite value when number is STARDUST_NUMBER_FLOAT. Otherwise, set real to zero.