# CaraSpace User Guide
CaraSpace is the Rust-facing way to generate Spytial diagrams from Rust data.
The Cargo package name is `caraspace`.
## What You Get
- Serde-based export from Rust values into the relational JSON shape expected by Spytial
- A derive macro, `SpytialDecorators`, for attaching layout and display metadata to Rust types
- `diagram(&value)` for quickly rendering a local HTML visualization in the browser
- `diagram_with_spec(&value, spec)` when you want to hand-write the Spytial YAML
## Install
Add the crate to your project:
```toml
[dependencies]
caraspace = "0.0"
serde = { version = "1", features = ["derive"] }
```
## Quick Start
```rust
use caraspace::{diagram, SpytialDecorators};
use serde::Serialize;
#[derive(Serialize, SpytialDecorators)]
#[attribute(field = "name")]
struct Company {
name: String,
employees: Vec<Person>,
}
#[derive(Serialize, SpytialDecorators)]
#[attribute(field = "name")]
#[align(selector = "reports_to", direction = "horizontal")]
struct Person {
name: String,
reports_to: Option<Box<Person>>,
}
fn main() {
let company = Company {
name: "Acme".to_string(),
employees: vec![Person {
name: "Alice".to_string(),
reports_to: None,
}],
};
diagram(&company);
}
```
## Core Workflow
1. Derive `Serialize` and `SpytialDecorators` on the Rust types you want to visualize.
2. Attach layout or styling attributes to those types.
3. Build a normal Rust value.
4. Call `diagram(&value)` for the generated spec, or `diagram_with_spec(&value, spec)` for a custom one.
## Main API
### `diagram`
```rust
use caraspace::diagram;
```
Uses compile-time decorator collection and opens a generated HTML file in the default browser.
### `diagram_with_spec`
```rust
use caraspace::diagram_with_spec;
```
Useful when you want to bypass derive-generated constraints and provide explicit YAML:
```rust
let spec = r#"
constraints:
- align:
selector: reports_to
direction: horizontal
directives:
- flag: hideDisconnected
"#;
```
### `export_json_instance`
```rust
use caraspace::export_json_instance;
```
Exports your Rust value without opening a browser. This is the right entry point if you want to integrate CaraSpace into another tool.
## Supported Decorator Attributes
These map onto the Rust builder and YAML serialization layer in `spytial_annotations`.
| `#[attribute(field = "...")]` | Show a field as an attribute |
| `#[flag(name = "...")]` | Set a global display flag |
| `#[orientation(selector = "...", directions = [...], negated = false)]` | Relative layout constraint (`negated` optional) |
| `#[align(selector = "...", direction = "horizontal" \| "vertical", negated = false)]` | Force alignment (`negated` optional) |
| `#[cyclic(selector = "...", direction = "...", negated = false)]` | Cyclic ordering (`negated` optional) |
| `#[group(..., negated = false)]` | Group by selector or field (`negated` optional) |
`negated = true` on any constraint emits the `hold: never` form spytial-core uses for disjunctive solving — i.e. "this constraint must NOT hold."
| `#[icon(selector = "...", path = "...", show_labels = true)]` | Set node icon |
| `#[edge_style(field = "...", value = "...", style = "dashed", weight = 2.0, show_label = true, hidden = false, filter = "...", selector = "...")]` | Style edges (color, line style, weight, visibility) |
| `#[projection(sig = "...")]` | Projection directive |
| `#[hide_field(field = "...")]` | Hide a relation |
| `#[hide_atom(selector = "...")]` | Hide selected atoms |
| `#[inferred_edge(name = "...", selector = "...")]` | Add inferred edges |
| `#[tag(to_tag = "...", name = "...", value = "...")]` | Tag matching atoms with computed attribute |
## Compile-Time Behavior
The derive macro walks common container types and includes decorators from nested types automatically.
Supported traversal patterns:
- `Vec<T>`
- `Option<T>`
- `Box<T>`
- nested combinations such as `Vec<Option<Box<T>>>`
This means decorating `Person` is usually enough for those decorators to appear when `Company` contains `Vec<Person>`.
## Runtime Annotations
If you need imperative control, use the `spytial_annotations` module directly:
```rust
use caraspace::spytial_annotations::{annotate_instance, AnnotationBuilder};
```
That path is better suited to advanced integrations than to the normal “derive and render” workflow.
## Recommended Development Commands
```bash
cargo test --lib --tests
cargo test --doc
cargo run --example demo
cargo run --example rbt
```
The `rbt` example is a representative insertion-balanced red-black tree (LLRB style) with decorator-driven coloring and left/right layout constraints.
## Docker Quickstart
Build:
```bash
docker build -t caraspace .
```
Run the red-black tree example (default):
```bash
docker run --rm -p 8080:8080 caraspace
```
Run a specific example:
```bash
docker run --rm -p 8080:8080 caraspace demo
```
In Docker, browser launch is disabled (`SPYTIAL_NO_OPEN=1`), so no GUI is opened inside the container.
After the example runs, the container serves the generated visualization at `http://localhost:8080/rust_viz_data.html`.
## Limitations and Expectations
- The browser rendering path relies on the embedded HTML template and bundled browser dependencies.
- Compile-time type walking is intentionally conservative; it handles common wrappers, not arbitrary type-level programming.
## Where To Read Next
- [README.md](./README.md) for the project overview
- [doc.md](./doc.md) for the design rationale and implementation details