1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! Relational JSON data model produced by [`crate::export_json_instance`].
//!
//! Every Rust value spytial visualizes is flattened into this shape:
//! a flat list of [`IAtom`](crate::jsondata::IAtom) nodes plus a flat list of
//! [`IRelation`](crate::jsondata::IRelation) edges grouped by name. The same
//! shape is what spytial-core consumes on the JavaScript side — these structs
//! are part of the public, stable API.
use Serialize;
/// A relational instance: the full set of atoms (nodes) and relations (edges)
/// extracted from a single Rust value.
///
/// Serialized as JSON in the HTML template and consumed by spytial-core's
/// `JSONDataInstance` constructor in the browser.
///
/// # Root atom
///
/// Atoms are stored in serialization order, so **`atoms[0]` is the root** — the
/// atom for the top-level value — because [`export_json_instance`] emits a
/// container/struct atom before recursing into its children. Reconstruction
/// relies on this: [`from_datum`] starts at `atoms[0]`, and [`from_datum_root`]
/// takes an explicit id for callers that build or reorder an instance themselves.
///
/// There is intentionally **no `rootId` field**. For `export` output it would be
/// redundant (the root is always `atoms[0]`, and the data is acyclic so the root
/// is also recoverable as the atom that no relation targets), and it would not
/// survive a spytial-core round-trip anyway, since unknown JSON keys are dropped.
/// A future producer that needs an explicit root should pass it to
/// [`from_datum_root`] rather than rely on a field that silently disappears.
///
/// [`export_json_instance`]: crate::export_json_instance
/// [`from_datum`]: crate::from_datum
/// [`from_datum_root`]: crate::from_datum_root
/// A single atom — one node in the relational graph.
///
/// Atoms are created from struct instances, collection containers (sequence,
/// tuple, map), and primitive leaves. `id` is unique within the instance,
/// `type` is the Rust type name (e.g. `"Person"`, `"i32"`, `"sequence"`),
/// and `label` is the human-readable text shown in the diagram.
/// A single tuple within a relation: the participating atoms and the type
/// of each position.
/// A relation — a named, typed edge set. All tuples in a relation share
/// the same arity and position types.
///
/// Examples: a field relation `name(Person, string)`, a sequence relation
/// `idx(sequence, index, T)`, or a map relation `map_entry(map, K, V)`.