# json_object
A simple, ergonomic, zero-dependency JSON library for Rust — **no macros crate needed**.
[](https://crates.io/crates/json_object)
[](https://docs.rs/json_object)
[](LICENSE)
---
## Features
- 🏗️ **`json!` macro** — build JSON with familiar literal syntax
- 🔍 **Dot-path access** — `obj.get_path("user.address.city")`
- ✏️ **Fluent builders** — `ObjectBuilder` and `ArrayBuilder`
- 📦 **Parse & Serialize** — compact and pretty-print output
- 🦀 **Zero dependencies** — pure `std` only
- ✅ **No unsafe code**
---
## Installation
```toml
[dependencies]
json_object = "0.1.0"
```
---
## Quick Start
```rust
use json_object::{Json, ObjectBuilder, ArrayBuilder, json};
fn main() {
// Build with macro
let obj = json!({
"name": "Rebon402",
"age": 30i64,
"active": true,
"score": 9.5f64,
"tags": ["rust", "json"],
"address": {
"city": "Bangkok"
},
"nothing": null
});
// Access values
println!("{}", obj["name"].as_str().unwrap()); // Rebon402
println!("{}", obj["age"].as_i64().unwrap()); // 30
println!("{}", obj["active"].as_bool().unwrap()); // true
// Dot-path access
let city = obj.get_path("address.city").unwrap();
println!("{}", city.as_str().unwrap()); // Bangkok
// Serialize
println!("{}", obj.to_json()); // compact
println!("{}", obj.to_pretty(" ")); // pretty
}
```
---
## Usage
### `json!` Macro
```rust
let v = json!({
"key": "value",
"num": 42i64,
"flag": true,
"list": [1i64, 2i64, 3i64],
"nested": { "x": 0i64 },
"empty": null
});
```
### Parse from string
```rust
let v = Json::parse(r#"{"name":"Bob","age":25}"#).unwrap();
assert_eq!(v["name"].as_str(), Some("Bob"));
```
### Reading values
```rust
v["key"].as_str() // Option<&str>
v["num"].as_i64() // Option<i64>
v["num"].as_f64() // Option<f64>
v["flag"].as_bool() // Option<bool>
v["list"].as_array() // Option<&Vec<Json>>
v["obj"].as_object() // Option<&HashMap<String, Json>>
// Index operator — returns Json::Null instead of panicking
let name = &v["missing"]; // Json::Null
// Array index
let first = &v["list"][0];
// Deep path
v.get_path("user.address.city") // Option<&Json>
```
### Mutating values
```rust
let mut obj = Json::new_object();
obj.set("name", "Carol");
obj.set("age", 28i64);
obj.remove("age");
obj.merge(&other_obj);
obj.contains_key("name"); // true
let mut arr = Json::new_array();
arr.push("hello");
arr.push(42i64);
```
### Fluent Builders
```rust
// Object
let user = ObjectBuilder::new()
.set("name", "Dave")
.set("age", 35i64)
.set_if(is_admin, "role", "admin") // conditional
.build();
// Array
let scores = ArrayBuilder::new()
.push(10i64)
.push(20i64)
.push_if(bonus, 50i64) // conditional
.extend(vec![1i64, 2i64, 3i64])
.build();
```
### Serialization
```rust
let compact = obj.to_json(); // {"name":"Rebon402","age":30}
let pretty = obj.to_pretty(" "); // 2-space indent
let tabbed = obj.to_pretty("\t"); // tab indent
```
### Type checks
```rust
v.is_null() // bool
v.is_bool() // bool
v.is_int() // bool
v.is_float() // bool
v.is_number() // int or float
v.is_str() // bool
v.is_array() // bool
v.is_object() // bool
```
### Iteration
```rust
// Array
for item in obj["tags"].iter_array() {
println!("{}", item);
}
// Object
for (key, val) in obj.iter_object() {
println!("{}: {}", key, val);
}
obj.keys() // Vec<&String>
obj.values() // Vec<&Json>
obj.len() // usize
```
### `From<T>` conversions
All common types convert automatically into `Json`:
| `bool` | `Json::Bool` |
| `i32`, `i64`, `u64`, `usize` | `Json::Int` |
| `f32`, `f64` | `Json::Float` |
| `&str`, `String` | `Json::Str` |
| `Vec<T>` | `Json::Array` |
| `Option<T>` | `Json::Null` or inner value |
---
## License
MIT — see [LICENSE](LICENSE)