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:

dust232B
#_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}
go366B
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
}
Result / 2B
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
Parsedocumentparse(text, format) returns an owned document.
Document.Rootnodedocument.root() returns the root node ID.
Document.Countcountdocument.count() returns the number of nodes.
Document.Readnode_viewdocument.read(id) returns a node view: kind, boolean, parent, position, first_child, next_sibling, key and text.
Document.ReadManynode_viewsdocument.read_many(start, capacity) reads consecutive node views.
Document.Membernodedocument.member(id, key) returns the first matching object member ID.
Document.Childrennode_viewsdocument.children(id) iterates the node views of a node's children in order.
Document.Membersnode_viewsdocument.members(id) iterates the members of an object node in order, each with its key.
Document.I64integerRead an exact signed integer.
Document.F64realRead a finite floating-point number.
Document.ClosenoneRelease the document handle.

Parse

parse(text, format) returns an owned document.

  • Formats are JSON, DUST, EDN and TRON.
  • Numbers outside i64 or finite f64 are refused at parse time.
go57B
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

ParameterTypeOwnershipDefaultMeaning
text[]byteValueRequiredEncoded input bytes in the selected format. TRON is binary.
formatFormatValueRequiredThe codec to use for this operation.

Errors

StatusWhen
StatusInvalidJSONJSON text is malformed
StatusInvalidArgumentthe text is malformed, the format is unknown or a number is outside i64 or finite f64
StatusOutOfMemorynative memory is exhausted

Examples

Parse the shared DUST expression fixture

expressionText holds these bytes:

text278B
// 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]
go111B
result, err := stardust.Parse(expressionText, stardust.DUST)
if err != nil {
	return err
}
defer result.Close()
Result / 293B
{
  // 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:

text1B
]
go105B
failed, result := stardust.Parse(malformedText, stardust.DUST)
if failed != nil {
	defer failed.Close()
}
Result / 137B
{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:

text1B
[
go174B
failed, err := stardust.Parse(malformedText, stardust.DUST)
if failed != nil {
	defer failed.Close()
}

var result *stardust.Error
if !errors.As(err, &result) {
	return err
}
Result / 137B
{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.

go37B
func (d *Document) Root() (ID, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Errors

StatusWhen
StatusClosedthe document is closed

Examples

document/root

inputText holds this document:

dust5B
x 41
go166B
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
	return err
}
defer source.Close()

result, err := source.Root()
if err != nil {
	return err
}
Result / 1B
0

C exports: stardust_document_root

Document.Count

document.count() returns the number of nodes.

go39B
func (d *Document) Count() (int, error)
  • Concurrency: Other calls can overlap this call, except the release of a handle that this call uses.

Errors

StatusWhen
StatusClosedthe document is closed

Examples

document/count

inputText holds this document:

dust5B
x 41
go167B
source, err := stardust.Parse(inputText, stardust.DUST)
if err != nil {
	return err
}
defer source.Close()

result, err := source.Count()
if err != nil {
	return err
}
Result / 1B
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.

go48B
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

ParameterTypeOwnershipDefaultMeaning
idIDValueRequiredA node ID within the receiver document.

Errors

StatusWhen
StatusInvalidArgumentid is not a node of the document
StatusClosedthe document is closed

Examples

document/read

inputText holds this document:

dust5B
x 41
go228B
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
}
Result / 145B
{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 i64 or f64.
go69B
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

ParameterTypeOwnershipDefaultMeaning
startIDValueRequiredThe first node ID of the consecutive read.
output[]NodeViewValueRequiredThe maximum number of node views to read. For output slices, the call uses the caller's slice length.

Errors

StatusWhen
StatusInvalidArgumentstart is past the last node or capacity is negative
StatusClosedthe document is closed

Examples

document/read_many

inputText holds this document:

dust5B
x 41
go321B
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]
Result / 145B
{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.
go56B
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

ParameterTypeOwnershipDefaultMeaning
idIDValueRequiredA node ID within the receiver document.
keystringValueRequiredThe object member name to find.

Errors

StatusWhen
StatusNotFoundthe object has no member with the key
StatusInvalidArgumentid is not an object node of the document
StatusClosedthe document is closed

Examples

document/member

inputText holds this document:

dust5B
x 41
go235B
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
}
Result / 1B
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_batch views per native call and follows next_sibling links.
  • 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.
go61B
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

ParameterTypeOwnershipDefaultMeaning
idIDValueRequiredA node ID within the receiver document.

Errors

StatusWhen
StatusInvalidArgumentid is not a node of the document
StatusClosedthe document is closed

Examples

document/children

seedText holds this document:

dust232B
#_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}
go265B
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++
}
Result / 1B
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.
go60B
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

ParameterTypeOwnershipDefaultMeaning
idIDValueRequiredA node ID within the receiver document.

Errors

StatusWhen
StatusInvalidArgumentid is not an object node of the document
StatusClosedthe document is closed

Examples

document/members

seedText holds this document:

dust232B
#_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}
go284B
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
}
Result / 12B
{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.

go44B
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

ParameterTypeOwnershipDefaultMeaning
idIDValueRequiredA node ID within the receiver document.

Errors

StatusWhen
StatusInvalidArgumentthe node is not an integer number
StatusClosedthe document is closed

Examples

document/i64

inputText holds this document:

dust5B
x 41
go295B
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
}
Result / 2B
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.

go46B
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

ParameterTypeOwnershipDefaultMeaning
idIDValueRequiredA node ID within the receiver document.

Errors

StatusWhen
StatusInvalidArgumentthe node is not a number or its value overflows f64
StatusClosedthe document is closed

Examples

document/f64

floatText holds this document:

dust4B
1.0
go227B
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
}
Result / 3B
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.
go26B
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:

dust9B
[+ ?x 1]
go208B
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()
Result / 33B
{
  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.

FieldTypeUnitAbsentMeaning
kindKindNone——
booleanboolNone—True only for true.
parentIDNoneNoNode—
positionintCount—Index within the parent container.
first_childIDNoneNoNode—
next_siblingIDNoneNoNode—
keystringNone—Member key of an object member, else empty.
textstringNone—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.

FieldTypeAbsentMeaning
parentIDNoNode—
kindKind——
booleanbool—Value of a boolean node.
numberNumericnilValue of a number node.
keystring—Member key when the parent is an object.
textstring—Value of a string node.