akari_serde

Crates.ioakari_serde
lib.rsakari_serde
version0.1.0
created_at2025-11-07 02:14:47.989697+00
updated_at2025-11-07 02:14:47.989697+00
descriptionSeamless bidirectional conversion between Akari Values and serde-compatible formats
homepage
repository
max_upload_size
id1920988
size38,311
とある科学のレッドストーン (Redstone-D)

documentation

https://docs.rs/akari_serde

README

akari_serde

Crates.io Documentation License

Seamless bidirectional conversion between Akari Values and serde-compatible formats

A lightweight bridge library that enables conversion between akari::Value and serialization formats supported by the serde ecosystem, starting with JSON.


✨ Features

  • 🔄 Bidirectional Conversion - Convert freely between akari::Valueserde_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:

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

🚀 Quick Start

Convert Akari Value → JSON Value

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

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

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:

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

    Value::Numerical(3.14)  →  json!(3)  // Precision lost
    
  • JSON → Akari: Non-finite numbers (NaN, Infinity) become 0.0

    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/ directory for more usage patterns:

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:

at your option.


🔗 Related Projects

  • akari - The core Akari value system
  • serde - Serialization framework for Rust
  • serde_json - JSON support for serde

Commit count: 0

cargo fmt