caraspace 0.0.1

Drop-in replacement for std::dbg! that opens an interactive diagram of Rust values (Spytial for Rust).
Documentation
# 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 | Purpose |
|----------|---------|
| `#[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."
| `#[atom_color(selector = "...", value = "...")]` | Color nodes |
| `#[size(selector = "...", height = 40, width = 60)]` | Set node size |
| `#[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