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
peopleText holds this document:
#_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}
people, err := stardust.Parse(peopleText, stardust.DUST)
if err != nil {
return err
}
defer people.Close()
root, err := people.Root()
if err != nil {
return err
}
ada, err := people.Member(root, "#_ada")
if err != nil {
return err
}
age, err := people.Member(ada, "age")
if err != nil {
return err
}
result, err := people.I64(age)
if err != nil {
return err
}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
| Operation | Returns | Summary |
|---|---|---|
| Parse | document | parse(text, format) returns an owned document. |
| Document.Root | node | document.root() returns the root node ID. |
| Document.Count | count | document.count() returns the number of nodes. |
| Document.Read | node_view | document.read(id) returns a node view: kind, boolean, parent, position, first_child, next_sibling, key and text. |
| Document.ReadMany | node_views | document.read_many(start, capacity) reads consecutive node views. |
| Document.Member | node | document.member(id, key) returns the first matching object member ID. |
| Document.Children | node_views | document.children(id) iterates the node views of a node's children in order. |
| Document.Members | node_views | document.members(id) iterates the members of an object node in order, each with its key. |
| Document.I64 | integer | Read an exact signed integer. |
| Document.F64 | real | Read a finite floating-point number. |
| Document.Close | none | Release the document handle. |
Parse
parse(text, format) returns an owned document.
- Formats are JSON, DUST, EDN and TRON.
- Numbers outside
i64or finitef64are refused at parse time.
func Parse(text []byte, format Format) (*Document, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
- Ownership: The caller owns the returned handle and releases it.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
text | []byte | Value | Required | Encoded input bytes in the selected format. TRON is binary. |
format | Format | Value | Required | The codec to use for this operation. |
Errors
| Status | When |
|---|---|
StatusInvalidJSON | JSON text is malformed |
StatusInvalidArgument | the text is malformed, the format is unknown or a number is outside i64 or finite f64 |
StatusOutOfMemory | native memory is exhausted |
Examples
Parse the shared DUST expression fixture
expressionText holds these bytes:
// 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]result, err := stardust.Parse(expressionText, stardust.DUST)
if err != nil {
return err
}
defer result.Close(){
// 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]}Report a malformed byte at offset zero
malformedText holds these bytes:
]
failed, result := stardust.Parse(malformedText, stardust.DUST)
if failed != nil {
defer failed.Close()
}{code invalid_dust
message Invalid_Syntax at offset 0
path null
field null
entity null
offset 0
status invalid_argument}Report malformed DUST
malformedText holds these bytes:
[
failed, err := stardust.Parse(malformedText, stardust.DUST)
if failed != nil {
defer failed.Close()
}
var result *stardust.Error
if !errors.As(err, &result) {
return err
}{code invalid_dust
message Unexpected_End at offset 2
path null
field null
entity null
offset 2
status invalid_argument}C exports: stardust_parse, stardust_document_error
Document.Root
document.root() returns the root node ID.
func (d *Document) Root() (ID, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Errors
| Status | When |
|---|---|
StatusClosed | the document is closed |
Examples
document/root
inputText holds this document:
x 41
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
result, err := source.Root()
if err != nil {
return err
}0
C exports: stardust_document_root
Document.Count
document.count() returns the number of nodes.
func (d *Document) Count() (int, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Errors
| Status | When |
|---|---|
StatusClosed | the document is closed |
Examples
document/count
inputText holds this document:
x 41
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
result, err := source.Count()
if err != nil {
return err
}2
C exports: stardust_document_count
Document.Read
document.read(id) returns a node view: kind, boolean, parent, position, first_child, next_sibling, key and text. Text contains string values, not number lexemes.
func (d *Document) Read(id ID) (NodeView, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
id | ID | Value | Required | A node ID within the receiver document. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | id is not a node of the document |
StatusClosed | the document is closed |
Examples
document/read
inputText holds this document:
x 41
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
result, err := source.Read(root)
if err != nil {
return err
}{kind object
boolean false
parent null
position 0
first_child 1
next_sibling null
key ""
text ""}C exports: stardust_document_read_many
Document.ReadMany
document.read_many(start, capacity) reads consecutive node views.
- Absent links use the binding's absent-node representation.
- Read numbers with
i64orf64.
func (d *Document) ReadMany(start ID, output []NodeView) (int, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
start | ID | Value | Required | The first node ID of the consecutive read. |
output | []NodeView | Value | Required | The maximum number of node views to read. For output slices, the call uses the caller's slice length. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | start is past the last node or capacity is negative |
StatusClosed | the document is closed |
Examples
document/read_many
inputText holds this document:
x 41
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
views := make([]stardust.NodeView, 1)
written, err := source.ReadMany(root, views)
if err != nil {
return err
}
views = views[:written]
result := views[0]{kind object
boolean false
parent null
position 0
first_child 1
next_sibling null
key ""
text ""}C exports: stardust_document_read_many
Document.Member
document.member(id, key) returns the first matching object member ID.
- A missing member reports
not_found. - The call finds an explicit null member.
func (d *Document) Member(id ID, key string) (ID, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
id | ID | Value | Required | A node ID within the receiver document. |
key | string | Value | Required | The object member name to find. |
Errors
| Status | When |
|---|---|
StatusNotFound | the object has no member with the key |
StatusInvalidArgument | id is not an object node of the document |
StatusClosed | the document is closed |
Examples
document/member
inputText holds this document:
x 41
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
result, err := source.Member(root, "x")
if err != nil {
return err
}1
C exports: stardust_document_member
Document.Children
document.children(id) iterates the node views of a node's children in order.
document.children(id) iterates the node views of the children of node id in document order.
- It reads
node_batchviews per native call and followsnext_siblinglinks. - A scalar node has no children.
- The views borrow the document, so nothing is released, and the document must stay open during the iteration.
- A failure is reported once, and then the iteration ends.
func (d *Document) Children(id ID) iter.Seq2[NodeView, error]- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
id | ID | Value | Required | A node ID within the receiver document. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | id is not a node of the document |
StatusClosed | the document is closed |
Examples
document/children
seedText holds this document:
#_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}
source, err := stardust.Parse(seedText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
result := 0
for _, err := range source.Children(root) {
if err != nil {
return err
}
result++
}4
C exports: stardust_document_read_many
Document.Members
document.members(id) iterates the members of an object node in order, each with its key.
document.members(id) iterates the members of the object node id in document order.
- Each member is a node view whose key is the member name; duplicate keys appear in order.
- The views borrow the document, so nothing is released, and the document must stay open during the iteration.
- A failure is reported once, and then the iteration ends.
func (d *Document) Members(id ID) iter.Seq2[NodeView, error]- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
id | ID | Value | Required | A node ID within the receiver document. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | id is not an object node of the document |
StatusClosed | the document is closed |
Examples
document/members
seedText holds this document:
#_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}
source, err := stardust.Parse(seedText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
result := ""
for view, err := range source.Members(root) {
if err != nil {
return err
}
result = view.Key
break
}{text #_ada}C exports: stardust_document_read_many
Document.I64
Read an exact signed integer.
document.i64(id) reads an exact integer number. A floating-point node is refused, even when its value is integral.
func (d *Document) I64(id ID) (int64, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
id | ID | Value | Required | A node ID within the receiver document. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | the node is not an integer number |
StatusClosed | the document is closed |
Examples
document/i64
inputText holds this document:
x 41
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
node, err := source.Member(root, "x")
if err != nil {
return err
}
result, err := source.I64(node)
if err != nil {
return err
}41
C exports: stardust_document_i64
Document.F64
Read a finite floating-point number.
document.f64(id) reads a number as a finite floating-point value. Integer conversion may round values outside the exact f64 integer range.
func (d *Document) F64(id ID) (float64, error)- Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.
Parameters
| Parameter | Type | Ownership | Default | Meaning |
|---|---|---|---|---|
id | ID | Value | Required | A node ID within the receiver document. |
Errors
| Status | When |
|---|---|
StatusInvalidArgument | the node is not a number or its value overflows f64 |
StatusClosed | the document is closed |
Examples
document/f64
floatText holds this document:
1.0
source, err := stardust.Parse(floatText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
root, err := source.Root()
if err != nil {
return err
}
result, err := source.F64(root)
if err != nil {
return err
}1.0
C exports: stardust_document_f64
Document.Close
Release the document handle.
close(handle) releases the handle.
- Do not use it after closure.
- Result documents remain usable after the handle that produces them closes.
func (d *Document) Close()- Concurrency: This call is the last use of the receiver and ends its ownership.
Examples
document/close
expressionText holds this document:
[+ ?x 1]
source, err := stardust.Parse(expressionText, stardust.DUST)
if err != nil {
return err
}
defer source.Close()
result, err := source.Serialize(stardust.DUST, 0)
if err != nil {
return err
}
source.Close(){
text '''
[+ ?x 1]
'''
}C exports: stardust_document_release
node_view
This record contains the result of read and read_many. The key and text fields borrow the document until it closes.
| Field | Type | Unit | Absent | Meaning |
|---|---|---|---|---|
kind | Kind | None | — | — |
boolean | bool | None | — | True only for true. |
parent | ID | None | NoNode | — |
position | int | Count | — | Index within the parent container. |
first_child | ID | None | NoNode | — |
next_sibling | ID | None | NoNode | — |
key | string | None | — | Member key of an object member, else empty. |
text | string | None | — | Value of a string, else empty. It can contain NUL. |
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.
| Field | Type | Absent | Meaning |
|---|---|---|---|
parent | ID | NoNode | — |
kind | Kind | — | — |
boolean | bool | — | Value of a boolean node. |
number | Numeric | nil | Value of a number node. |
key | string | — | Member key when the parent is an object. |
text | string | — | Value of a string node. |