akari_serde 0.1.0

Seamless bidirectional conversion between Akari Values and serde-compatible formats
Documentation
# akari_serde

[![Crates.io](https://img.shields.io/crates/v/akari_serde.svg)](https://crates.io/crates/akari_serde)
[![Documentation](https://docs.rs/akari_serde/badge.svg)](https://docs.rs/akari_serde)
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE)

> **Seamless bidirectional conversion between Akari Values and serde-compatible formats**

A lightweight bridge library that enables conversion between [`akari::Value`](https://docs.rs/akari) and serialization formats supported by the [serde](https://serde.rs) ecosystem, starting with JSON.

---

## ✨ Features

- 🔄 **Bidirectional Conversion** - Convert freely between `akari::Value``serde_json::Value`
- 🛡️ **Type-Safe** - Leverages Rust's type system with zero runtime overhead
- 🎯 **Orphan Rule Solution** - Uses the `Trans` mediator pattern to bridge foreign types
- 📦 **Zero Dependencies** - Only depends on `akari` and `serde_json`
- 🚀 **Efficient** - Minimal allocations, recursive conversions optimized for performance

---

## 📦 Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
akari = "0.2.4"
akari_serde = "0.1.0"
```

---

## 🚀 Quick Start

### Convert Akari Value → JSON Value

```rust
use akari::Value;
use akari_serde::Trans;
use serde_json::Value as JsonValue;

// Create an Akari value
let akari_value = Value::Boolean(true);

// Convert to serde_json Value
let json_value: JsonValue = Trans::from(akari_value).into();

assert_eq!(json_value, serde_json::json!(true));
```

### Convert JSON Value → Akari Value

```rust
use akari::Value;
use akari_serde::Trans;
use serde_json::json;

// Create a JSON value
let json_value = json!({
    "name": "Alice",
    "age": 30,
    "active": true
});

// Convert to Akari Value
let akari_value: Value = Trans::from(json_value).into();

// Access as Akari types
match akari_value {
    Value::Dict(map) => {
        println!("Name: {:?}", map.get("name"));
        println!("Age: {:?}", map.get("age"));
    }
    _ => unreachable!(),
}
```

### Working with Complex Structures

```rust
use akari::Value;
use akari_serde::Trans;
use serde_json::json;

// Complex nested JSON
let json_data = json!({
    "users": [
        {"id": 1, "name": "Alice"},
        {"id": 2, "name": "Bob"}
    ],
    "count": 2,
    "active": true
});

// Convert to Akari (for processing)
let akari_value: Value = Trans::from(json_data).into();

// Process with Akari...
// (manipulate, query, transform)

// Convert back to JSON (for serialization)
let json_output: serde_json::Value = Trans::from(akari_value).into();
```

---

## 🏗️ Architecture

### The `Trans` Mediator Pattern

Rust's orphan rule prevents directly implementing `From<JsonValue>` for `akari::Value` (or vice versa) since both are foreign types. The `Trans` enum solves this elegantly:

```rust
pub enum Trans {
    Akari(Value),       // Wraps akari::Value
    Serde(JsonValue),   // Wraps serde_json::Value
}
```

**Conversion Flow:**

```
akari::Value  →  Trans::Akari(v)  →  Trans  →  serde_json::Value
                       ↑                              ↓
                       └──────── Trans::Serde(v) ─────┘
```

This two-step conversion is zero-cost at runtime thanks to Rust's optimization.

---

## 🔬 Type Mappings

### Akari → JSON

| Akari Type       | JSON Type          | Notes                                    |
|------------------|--------------------|------------------------------------------|
| `Value::None`    | `JsonValue::Null`  | Direct mapping                           |
| `Value::Boolean` | `JsonValue::Bool`  | Direct mapping                           |
| `Value::Numerical(f64)` | `JsonValue::Number` | Converted to `i64` (lossy for floats) |
| `Value::Str`     | `JsonValue::String`| Direct mapping                           |
| `Value::List`    | `JsonValue::Array` | Recursive conversion                     |
| `Value::Dict`    | `JsonValue::Object`| Recursive conversion                     |

### JSON → Akari

| JSON Type          | Akari Type         | Notes                                    |
|--------------------|--------------------|------------------------------------------|
| `JsonValue::Null`  | `Value::None`      | Direct mapping                           |
| `JsonValue::Bool`  | `Value::Boolean`   | Direct mapping                           |
| `JsonValue::Number`| `Value::Numerical` | Converted to `f64` (may lose precision)  |
| `JsonValue::String`| `Value::Str`       | Direct mapping                           |
| `JsonValue::Array` | `Value::List`      | Recursive conversion                     |
| `JsonValue::Object`| `Value::Dict`      | Recursive conversion                     |

---

## ⚠️ Important Notes

### Numerical Precision

- **Akari → JSON**: Converts `f64` to `i64`, losing fractional parts
  ```rust
  Value::Numerical(3.14)json!(3)  // Precision lost
  ```

- **JSON → Akari**: Non-finite numbers (`NaN`, `Infinity`) become `0.0`
  ```rust
  json!(NaN)Value::Numerical(0.0)  // Fallback to zero
  ```

### Null Handling

- JSON's `null` maps to Akari's `Value::None`
- Both representations are preserved during round-trip conversion

---

## 📚 Examples

Check out the [`examples/`](examples/) directory for more usage patterns:

```bash
cargo run --example json_conversion
```

---

## 🛣️ Roadmap

- [ ] Support for more serde formats:
  - [ ] YAML (`serde_yaml`)
  - [ ] TOML (`toml`)
  - [ ] MessagePack (`rmp-serde`)
  - [ ] BSON (`bson`)
- [ ] Improved numerical conversion strategies
- [ ] Optional features for format-specific optimizations
- [ ] Benchmarks and performance tuning

---

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

---

## 📄 License

This project is dual-licensed under:

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

at your option.

---

## 🔗 Related Projects

- [**akari**]https://fds.rs/akari/ - The core Akari value system
- [**serde**]https://serde.rs - Serialization framework for Rust
- [**serde_json**]https://docs.rs/serde_json - JSON support for serde

---

<div align="center">

</div>