The Document model
Build, navigate, and mutate a Document — the one tree every format reads into.
A Document is a tree: an ordered list of labeled edges. There is no separate array type — a label that repeats is the array. This one idea is why JSON, YAML, TOML, XML, and Omnist's own OML format can all be read into (and written back out from) the exact same structure.
doc(value) builds a Document from plain Python — a dict becomes an edge list, and a key whose value is a list expands into one edge per item:
from omnist import doc
d = doc({"name": "Ann", "tag": ["x", "y"]})
d.labels() # every distinct label present
d.count("tag") # how many edges share this label
d.get_one("name").value # the single edge under a non-repeated label
[t.value for t in d.get("tag")] # every value under a repeated label
d.to_data() # the raw edge list
d.to_grouped() # JSON-shaped: repeated labels become a listOutput
labels: ['name', 'tag']
count tag: 2
get_one name value: Ann
get tag values: ['x', 'y']
to_data: [('name', 'Ann'), ('tag', 'x'), ('tag', 'y')]
to_grouped: {'name': 'Ann', 'tag': ['x', 'y']}A Document is mutated through a guarded API — add is how an array grows, set replaces every edge under a label with one, and remove drops a label entirely:
d.add("tag", "z") # append an edge -- the array grows
d.set("name", "Bob") # replace every 'name' edge with one
d.remove("tag") # drop every 'tag' edgeOutput
after add: {'name': 'Ann', 'tag': ['x', 'y', 'z']}
after set: {'name': 'Bob', 'tag': ['x', 'y', 'z']}
after remove: {'name': 'Bob'}