From Value
facet-value provides a dynamic Value type and conversion to/from any Facet type. Use it for format-agnostic data manipulation, testing, or bridging between different serialization formats.
Happy Path
Simple Struct
Deserialize a Value map into a struct with basic fields.
Value Input
{
name: "Alice",
age: 30,
email: "alice@example.com",
}Target Type
#[derive(Facet)]
struct Person {
name: String,
<span style="color:#7aa2f7;">age</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">u32</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">email</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Option</span><span style="color:#a9b1d6;"><</span><span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">>,</span>
}
Success
Person {
name: "Alice",
age: 30,
email: Option::Some("alice@example.com"),
}Nested Structs
Nested structs are deserialized recursively.
Value Input
{
person: {
name: "Bob",
age: 42,
email: null,
},
address: {
street: "123 Main St",
city: "Springfield",
zip: "12345",
},
department: "Engineering",
}Target Type
#[derive(Facet)]
struct Employee {
person: Person,
<span style="color:#7aa2f7;">address</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Address</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">department</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
}
#[derive(Facet)]
struct Address {
street: String,
<span style="color:#7aa2f7;">city</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">zip</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
}
#[derive(Facet)]
struct Person {
name: String,
<span style="color:#7aa2f7;">age</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">u32</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">email</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Option</span><span style="color:#a9b1d6;"><</span><span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">>,</span>
}
Success
Employee {
person: Person {
name: "Bob",
age: 42,
email: Option::None,
},
address: Address {
street: "123 Main St",
city: "Springfield",
zip: "12345",
},
department: "Engineering",
}Unit Enum Variant
A string value deserializes into a unit variant.
Value Input
"Active"Target Type
#[derive(Facet)]
#[repr(u8)]
enum Status {
Active,
Inactive<span style="color:#a9b1d6;">,</span>
Pending<span style="color:#a9b1d6;">,</span>
}
Success
Status::ActiveTuple Enum Variant
Externally tagged enum: {"Variant": content}.
Value Input
{
Text: "Hello world!",
}Target Type
#[derive(Facet)]
#[repr(u8)]
enum Message {
Text(String),
Number<span style="color:#a9b1d6;">(</span><span style="color:#2ac3de;">i32</span><span style="color:#a9b1d6;">),</span>
Data <span style="color:#a9b1d6;">{</span>
<span style="color:#7aa2f7;">id</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">u64</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">payload</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
<span style="color:#a9b1d6;">},</span>
}
Success
Message::Text("Hello world!")Struct Enum Variant
Struct variants deserialize with named fields.
Value Input
{
Data: {
id: 42,
payload: "secret data",
},
}Target Type
#[derive(Facet)]
#[repr(u8)]
enum Message {
Text(String),
Number<span style="color:#a9b1d6;">(</span><span style="color:#2ac3de;">i32</span><span style="color:#a9b1d6;">),</span>
Data <span style="color:#a9b1d6;">{</span>
<span style="color:#7aa2f7;">id</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">u64</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">payload</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">String</span><span style="color:#a9b1d6;">,</span>
<span style="color:#a9b1d6;">},</span>
}
Success
Message::Data {
id: 42,
payload: "secret data",
}Vec Deserialization
Arrays deserialize into Vec<T>.
Value Input
[
1,
2,
3,
4,
5,
]Target Type
Success
Vec<i32> [1, 2, 3, 4, 5]Fixed-Size Array
Arrays with exact length deserialize into [T; N].
Value Input
[
"a",
"b",
"c",
]Target Type
Success
[String; 3] ["a", "b", "c"]HashMap
Objects deserialize into HashMap<String, T>.
Value Input
{
x: 10,
y: 20,
z: 30,
}Target Type
Success
HashMap<String, i32> [
"x" => 10,
"y" => 20,
"z" => 30,
]Nested Collections
null values become None in Option<T>.
Value Input
[
1,
null,
3,
null,
5,
]Target Type
Success
Vec<Option> [Option::Some(1), Option::None, Option::Some(3), Option::None, Option::Some(5)]Default Field Values
Fields marked with #[facet(default)] use Default::default() when missing.
Value Input
{
name: "minimal",
}Target Type
#[derive(Facet)]
struct Config {
name: String,
<span style="color:#7aa2f7;">enabled</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">bool</span><span style="color:#a9b1d6;">,</span>
<span style="color:#7aa2f7;">max_retries</span><span style="color:#a9b1d6;">:</span> <span style="color:#2ac3de;">Option</span><span style="color:#a9b1d6;"><</span><span style="color:#2ac3de;">u32</span><span style="color:#a9b1d6;">>,</span>
}
Success
Config {
name: "minimal",
enabled: false,
max_retries: Option::None,
}Errors
Error: Type Mismatch
Trying to deserialize a string as an integer.
Error
× reflection error: Operation failed on shape i32: Failed to parse string value
Error:
× input.json
╭────
1 │ "not a number"
· ───────┬──────
· ╰── this value
╰────
Error: Number Out of Range
Value 1000 is too large for u8 (max 255).
Error
× number out of range: 1000 out of range for u8
Error:
× input.json
╭────
1 │ 1000
· ──┬─
· ╰── this value: 1000 out of range for u8
╰────
Error: Wrong Array Length
Array has 4 elements but target type expects exactly 3.
Error
× unsupported: fixed array has 3 elements but got 4
Error:
× input.json
╭─[1:1]
1 │ ╭─▶ [
2 │ │ 1,
3 │ │ 2,
4 │ │ 3,
5 │ │ 4
6 │ ├─▶ ]
· ╰──── this value
╰────
Error: Invalid Enum Variant
"Unknown" is not a valid variant of Status.
Error
× reflection error: Operation failed on shape Status: No variant found with the given name
Error:
× input.json
╭────
1 │ "Unknown"
· ────┬────
· ╰── this value
╰────
Error:
× target.rs
╭─[1:24]
1 │ ╭─▶ #[derive(Facet)]
2 │ │ #[repr(u8)]
3 │ │ enum Status {
4 │ │ Active,
5 │ │ Inactive,
6 │ │ Pending,
7 │ ├─▶ }
· ╰──── target type
╰────
Error: Expected Object, Got Array
Cannot deserialize an array as a struct.
Error
× type mismatch: expected object, got Array
Error:
× input.json
╭─[1:1]
1 │ ╭─▶ [
2 │ │ 1,
3 │ │ 2,
4 │ │ 3
5 │ ├─▶ ]
· ╰──── got Array
╰────
Error:
× target.rs
╭─[1:24]
1 │ ╭─▶ #[derive(Facet)]
2 │ │ struct Person {
3 │ │ name: String,
4 │ │ age: u32,
5 │ │ email: Option<String>,
6 │ ├─▶ }
· ╰──── expected object
╰────