xopsy 0.1.2

Structural pattern matching DSL for JSON. Perform declarative diagnostics and surgical in-place updates on dynamic data.
Documentation
# Xopsy πŸ©ΊπŸ“„

**The Diagnostic Prism for JSON in Rust.**

> *Forged as a byproduct of the **Cognitive OS** architecture.*

`xopsy` is a structural pattern matching DSL designed to perform instant diagnostics on `serde_json::Value`.

Standard Rust pattern matching struggles with the dynamic, nested nature of JSON. `xopsy` solves this by allowing you to **describe the shape** you expect and **extract data** in a single, declarative breath.

**"Don't parse. Recognize."**

## ⚑ Signal vs. Noise

**Before Xopsy (Standard Serde Pain):**
```rust,ignore
// The "Option Hell" - Buried in noise
if let Some(obj) = data.as_object() {
    if let Some(users) = obj.get("users") {
        if let Some(user_arr) = users.as_array() {
            for user in user_arr {
                if user.get("active") == Some(&json!(true)) {
                    // Even extracting a string is painful...
                    if let Some(name) = user.get("name").and_then(|v| v.as_str()) {
                         println!("Found active user: {}", name);
                    }
                }
            }
        }
    }
}
```

**After Xopsy:**
```rust,ignore
// The Clear Vision
use xopsy::scope;

scope!(data, {
    "users": [
        { "active": true, "name": ?name }, // Check & Capture
        ..
    ]
} => println!("Found active user: {}", name));
```

---

## πŸ“¦ Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
xopsy = "0.1.2"
## License

This project is licensed under either of

* Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or [http://www.apache.org/licenses/LICENSE-2.0]http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT]LICENSE-MIT or [http://opensource.org/licenses/MIT]http://opensource.org/licenses/MIT)

at your option.
serde_json = "1.0"
```

---

### ⚠️ Note on Recursion Limit

`xopsy` relies on recursive macro expansion. For extremely deep JSON structures or very long arrays (e.g., hundreds of elements), you might hit the compiler's default recursion limit.

If you encounter a `recursion limit reached` error, simply add this attribute to your crate root (`main.rs` or `lib.rs`):

```rust,ignore
#![recursion_limit = "256"] // Increase as needed
```

---

## πŸš€ Core Features

`xopsy` provides two powerful macros:

1.  **`scope!`**: **Immutable Read.** Safely extracts values from complex structures using tuple-binding.
2.  **`focus!`**: **Mutable Injection.** Drills into the JSON and injects code for modification (Best used with [Opejson]https://github.com/rhetro/opejson).

### 1. The Diagnostics: `scope!`

Use this when you want to **read** data without modifying it. It returns the result of the block.

**Feature: Drill Syntax & Recursive Capture**

```rust,ignore
use xopsy::scope;
use serde_json::json;

fn main() {
    let data = json!({
        "network": {
            "ipv4": "192.168.1.1",
            "config": {
                "retry": 3,
                "mode": "auto"
            }
        }
    });

    let (ip, retries) = scope!(data, {
        // 1. Drill Syntax: Skip nesting with dot notation ("a"."b")
        "network"."ipv4": ?addr,
        
        // 2. Recursive Capture: Capture the object AND drill inside it
        "network"."config": ?{
            "retry": ?r,
            "mode": "auto" // Validation
        }
    } => {
        (addr.as_str().unwrap(), r.as_i64().unwrap())
    },
    // Fallback pattern
    _ => panic!("Structure mismatch"));

    assert_eq!(ip, "192.168.1.1");
    assert_eq!(retries, 3);
}
```

### 2. The Surgery: `focus!`

Use this when you want to **modify** deep structures.
`focus!` uses a **CPS (Continuation-Passing Style)** architecture to safely pass a `&mut Value` into your code block, bypassing Rust's strict borrowing rules.

```rust
use xopsy::focus;
use serde_json::json;

fn main() {
    let mut data = json!({
        "users": [
            { "id": 101, "config": {} },
            { "id": 102, "config": {} }
        ]
    });

    // GOAL: Find user 101 and mutate its config in place.

    focus!(data, {
        "users": [
            { "id": 101, "config": ?conf },
            ..
        ]
    } => {
        // 'conf' is a &mut Value pointing directly to the config object.
        // You can mutate it freely here.
        conf["enabled"] = json!(true);
    });
}
```

> **Pro Tip:** If you need to nest `focus!` calls, remember to dereference the variable (e.g., `focus!(*parent_ref, ...)`).


---

## πŸ“– Syntax Guide

The Xopsy DSL is designed to be intuitive and minimal.

| Syntax | Description | Example |
|:---|:---|:---|
| **`?var`** | **Capture.** Binds the value to the variable `var`. | `"id": ?my_id` |
| **`?{ ... }`** | **Recursive Capture.** Validates structure AND captures inner fields. | `"user": ?{ "name": ?n }` |
| **`"key": val`** | **Check.** Validates that the key exists and equals `val`. | `"status": 200` |
| **`"a"."b"`** | **Drill.** Syntactic sugar for nested objects. | `"system"."cpu": ?usage` |
| **`[p1, p2]`** | **Exact Array.** Matches an array of exactly 2 elements. | `[10, 20]` |
| **`[p1, ..]`** | **Head Match.** Matches start, ignores the rest. | `["header", ..]` |
| **`_`** | **Wildcard.** Matches anything (existence check). | `"meta": _` |
| **`null`** | **Null Check.** Explicitly matches JSON null. | `"error": null` |

---

## 🧠 Design Philosophy

### 1. Abstraction Without Runtime Weight
Xopsy expands into raw reference checks.
Nothing runs at runtime except what you would have written yourself.

### 2. The "Inversion" Architecture
To handle Rust's strict borrowing rules (especially `&mut`), `focus!` does not "return" values. Instead, it **injects your code** into the borrow scope (CPS).
This guarantees that the mutable references are valid, distinct, and safe to use, solving the common "fighting the borrow checker" problem when mutating JSON.

---

## 🀝 Relationship with Opejson

**The Ultimate Combo:** Use **Xopsy** to find the context, and **[Opejson](https://github.com/rhetro/opejson)** to perform the surgery.

Xopsy finds the context.  
**[Opejson](https://crates.io/crates/opejson)** shapes the structure.

```rust,ignore
use xopsy::focus;
use opejson::genesis::suture;
use serde_json::json;

// Before
let mut data = json!({
    "system": {
        "services": {
            "auth": {
                "config": {}
            }
        }
    }
});

// 1. Locate (Xopsy)
focus!(data, {
    "system"."services"."auth"."config": ?conf
} => {
    // 2. Operate (Opejson - Genesis Mode)
    // Grow a deeply nested feature flag
    suture!(conf,
        . "features" . "beta" . "v2" . "enabled" = true
    );
});

// After
assert_eq!(data, json!({
    "system": {
        "services": {
            "auth": {
                "config": {
                    "features": {
                        "beta": {
                            "v2": {
                                "enabled": true
                            }
                        }
                    }
                }
            }
        }
    }
}));
```

---

## License

This project is licensed under either of

* Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or [http://www.apache.org/licenses/LICENSE-2.0]http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT]LICENSE-MIT or [http://opensource.org/licenses/MIT]http://opensource.org/licenses/MIT)

at your option.