facet-json Comprehensive Showcase
Basic Struct
Simple struct with optional field serialized to JSON.
Target Type
#[derive(Facet)] struct Person { name: String, age: u32, email: Option<String>, }
Success
Person {
name: "Alice",
age: 30,
email: Option<String>::Some("alice@example.com"),
}
JSON Output
{ "name": "Alice", "age": 30, "email": "alice@example.com" }
Nested Structs
Struct containing nested struct and vector.
Target Type
#[derive(Facet)] struct Company { name: String, address: Address, employees: Vec<String>, } #[derive(Facet)] struct Address { street: String, city: String, }
Success
Company {
name: "Acme Corp",
address: Address {
street: "123 Main St",
city: "Springfield",
},
employees: Vec<String> [
"Bob",
"Carol",
"Dave",
],
}
JSON Output
{ "name": "Acme Corp", "address": { "street": "123 Main St", "city": "Springfield" }, "employees": [ "Bob", "Carol", "Dave" ] }
Externally Tagged Enum (default)
Default enum serialization with external tagging: {"Variant": content}
Target Type
Success
[Message; 3] [
Message::Text("Hello, world!"),
Message::Image {
url: "https://example.com/cat.jpg",
width: 800,
},
Message::Ping,
]
JSON Output
[ { "Text": "Hello, world!" }, { "Image": { "url": "https://example.com/cat.jpg", "width": 800 } }, "Ping" ]
Internally Tagged Enum
Enum with internal tagging using #[facet(tag = "type")] - variant name becomes a field.
Target Type
Success
[ApiResponse; 2] [
ApiResponse::Success {
data: "Operation completed",
},
ApiResponse::Error {
code: 404,
message: "Not found",
},
]
JSON Output
[ { "type": "Success", "data": "Operation completed" }, { "type": "Error", "code": 404, "message": "Not found" } ]
Adjacently Tagged Enum
Enum with adjacent tagging using #[facet(tag = "t", content = "c")] - variant name and content are separate fields.
Target Type
Success
[Event; 3] [
Event::Click {
x: 100,
y: 200,
},
Event::KeyPress(A),
Event::Resize,
]
JSON Output
[ { "t": "Click", "c": { "x": 100, "y": 200 } }, { "t": "KeyPress", "c": "A" }, { "t": "Resize" } ]
Untagged Enum
Enum with #[facet(untagged)] - no tagging, relies on JSON structure to determine variant.
Target Type
Success
[StringOrNumber; 2] [
StringOrNumber::Str("hello"),
StringOrNumber::Num(42),
]
JSON Output
[ "hello", 42 ]
Maps with String Keys
HashMap with string keys serializes to JSON object.
Target Type
Success
HashMap<String, i32> [
"two" => 2,
"one" => 1,
]
JSON Output
{ "two": 2, "one": 1 }
Maps with Integer Keys
HashMap with integer keys - keys are stringified for JSON compatibility.
Target Type
Success
HashMap<i32, &str> [
1 => "one",
2 => "two",
]
JSON Output
{ "1": "one", "2": "two" }
Tuple Struct
Tuple struct serializes as JSON array.
Target Type
#[derive(Facet)] struct Point(i32, i32, i32);
Success
Point(
10,
20,
30,
)
JSON Output
[ 10, 20, 30 ]
Compact JSON Output
Compact serialization - all on one line, minimal whitespace.
Target Type
#[derive(Facet)] struct Config { debug: bool, max_connections: u32, endpoints: Vec<String>, }
Success
Config {
debug: true,
max_connections: 100,
endpoints: Vec<String> [
"https://api1.example.com",
"https://api2.example.com",
],
}
JSON Output
{"debug":true,"max_connections":100,"endpoints":["https://api1.example.com","https://api2.example.com"]}
Pretty JSON Output
Pretty-printed serialization - formatted with indentation and newlines.
Target Type
#[derive(Facet)] struct Config { debug: bool, max_connections: u32, endpoints: Vec<String>, }
Success
Config {
debug: true,
max_connections: 100,
endpoints: Vec<String> [
"https://api1.example.com",
"https://api2.example.com",
],
}
JSON Output
{ "debug": true, "max_connections": 100, "endpoints": [ "https://api1.example.com", "https://api2.example.com" ] }
Syntax Error: Unexpected Character
Invalid character at the start of JSON input.
JSON Input
@invalid
Target Type
Error
json::token
× unexpected character: '@' (while parsing i32)
╭────
1 │ @invalid
· ┬
· ╰── unexpected '@', expected i32
╰────
Syntax Error: Invalid Character in Object
Invalid character appears mid-parse with surrounding context visible.
JSON Input
{"name": "test", "value": @bad}
Target Type
#[derive(Facet)] struct Data { name: String, value: i32, }
Error
json::token
× unexpected character: '@' (while parsing i32)
╭────
1 │ {"name": "test", "value": @bad}
· ┬
· ╰── unexpected '@', expected i32
╰────
Syntax Error: Multiline JSON
Error location is correctly identified in multiline JSON.
JSON Input
{ "name": "test", "count": ???, "active": true }
Target Type
#[derive(Facet)] struct Config { name: String, count: i32, active: bool, }
Error
json::token
× unexpected character: '?' (while parsing i32)
╭─[3:12]
2 │ "name": "test",
3 │ "count": ???,
· ┬
· ╰── unexpected '?', expected i32
4 │ "active": true
╰────
Unknown Field
JSON contains a field that doesn't exist in the target struct.
The error shows the unknown field and lists valid alternatives.
JSON Input
{"username": "alice", "emial": "alice@example.com"}
Target Type
#[derive(Facet)] #[facet(deny_unknown_fields)] struct User { username: String, email: String, }
Error
json::unknown_field
× unknown field emial, expected one of: ["username", "email"] (did you mean email?)
╭────
1 │ {"username": "alice", "emial": "alice@example.com"}
· ───┬───
· ╰── unknown field 'emial' - did you mean 'email'?
╰────
Type Mismatch
JSON value type doesn't match the expected Rust type.
JSON Input
{"id": 42, "name": 123}
Target Type
#[derive(Facet)] struct Item { id: u64, name: String, }
Error
json::type_mismatch
× type mismatch: expected String, got unsigned integer
╭────
1 │ {"id": 42, "name": 123}
· ─┬─
· ╰── expected String, got unsigned integer
╰────
Missing Required Field
JSON is missing a required field that has no default.
JSON Input
{"host": "localhost"}
Target Type
#[derive(Facet)] struct ServerConfig { host: String, port: u16, }
Error
json::missing_field
× missing required field port
╭────
1 │ {"host": "localhost"}
· ┬ ┬
· │ ╰── object ended without field port
· ╰── object started here
╰────
Number Out of Range
JSON number is too large for the target integer type.
JSON Input
{"count": 999999999999}
Target Type
#[derive(Facet)] struct Counter { count: u32, }
Error
json::number_out_of_range
× number 999999999999 out of range for u32
╭────
1 │ {"count": 999999999999}
· ──────┬─────
· ╰── out of range for u32
╰────
Expected Array, Got String
JSON has a string where an array was expected.
JSON Input
{"items": "not an array"}
Target Type
#[derive(Facet)] struct Container { items: Vec<i32>, }
Error
json::unexpected_token
× unexpected token: got "not an array", expected '['
╭────
1 │ {"items": "not an array"}
· ───────┬──────
· ╰── expected '[', got '"not an array"'
╰────
Tuple Size Mismatch
JSON array has wrong number of elements for tuple type.
JSON Input
[1, 2, 3]
Target Type
#[derive(Facet)] struct (…)(i32, i32);
Error
json::unexpected_token
× unexpected token: got ,, expected ']'
╭────
1 │ [1, 2, 3]
· ┬
· ╰── expected ']', got ','
╰────
Unknown Enum Variant
JSON specifies a variant name that doesn't exist.
JSON Input
"Unknown"
Target Type
#[derive(Facet)] #[repr(u8)] enum Status { Active, Inactive, Pending, }
Error
json::reflect
× reflection error: Operation failed on shape Status: No variant found with the given name
Wrong Variant Format
Externally tagged enum expects {"Variant": content} but got wrong format.
JSON Input
{"type": "Text", "content": "hello"}
Target Type
#[derive(Facet)] #[repr(u8)] enum MessageError { Text(String), Number(i32), }
Error
json::reflect
× reflection error: Operation failed on shape MessageError: No variant found with the given name
Internally Tagged Enum: Missing Tag Field
Internally tagged enum requires the tag field to be present.
JSON Input
{"id": "123", "method": "ping"}
Target Type
#[derive(Facet)] #[repr(u32)] #[facet(tag = "type")] enum Request { Ping { id: String, }, Echo { id: String, message: String, }, }
Error
json::reflect
× reflection error: Operation failed on shape Request: No variant found with the given name
Trailing Data After Valid JSON
Valid JSON followed by unexpected extra content.
JSON Input
42 extra stuff
Target Type
Error
json::token
× unexpected character: 'e'
Empty Input
No JSON content at all.
JSON Input
Target Type
Error
json::unexpected_token
× unexpected token: got EOF, expected scalar value
╭────
╰────
Error with Unicode Content
Error reporting handles unicode correctly.
JSON Input
{"emoji": "🎉🚀", "count": nope}
Target Type
#[derive(Facet)] struct EmojiData { emoji: String, count: i32, }
Error
json::token
× unexpected character: 'n' (while parsing i32)
╭────
1 │ {"emoji": "🎉🚀", "count": nope}
· ──┬─
· ╰── unexpected 'n', expected i32
╰────