Skip to main content

from_str

Function from_str 

Source
pub fn from_str<T>(input: &str) -> Result<T, DeserializeError>
where T: Facet<'static>,
Expand description

Deserialize a value from a JSON string into an owned type.

This is the recommended default for most use cases. The input does not need to outlive the result, making it suitable for deserializing from temporary buffers (e.g., HTTP request bodies).

Types containing &str fields cannot be deserialized with this function; use String or Cow<str> instead. For zero-copy deserialization into borrowed types, use from_str_borrowed.

ยงExample

use facet::Facet;
use facet_json::from_str;

#[derive(Facet, Debug, PartialEq)]
struct Person {
    name: String,
    age: u32,
}

let json = r#"{"name": "Alice", "age": 30}"#;
let person: Person = from_str(json).unwrap();
assert_eq!(person.name, "Alice");
assert_eq!(person.age, 30);
Examples found in repository?
examples/profile_twitter.rs (line 206)
201fn main() {
202    let json = std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/../../twitter.json"))
203        .expect("twitter.json not found");
204
205    for _ in 0..100 {
206        let result: Twitter = from_str(&json).unwrap();
207        black_box(result);
208    }
209}
More examples
Hide additional examples
examples/profile_citm.rs (line 84)
76fn main() {
77    let json = std::fs::read_to_string(concat!(
78        env!("CARGO_MANIFEST_DIR"),
79        "/../../citm_catalog.json"
80    ))
81    .expect("citm_catalog.json not found");
82
83    for _ in 0..100 {
84        let result: CitmCatalog = from_str(&json).unwrap();
85        black_box(result);
86    }
87}
examples/debug_issue_2020.rs (line 52)
35fn main() {
36    let json = r#"{
37    "container": {
38      "items": {
39        "a": {
40          "kind": "TypeA",
41          "value": 42.0,
42          "data": {
43            "x": [1.0, 2.0],
44            "y": [100.0, 200.0]
45          }
46        }
47      }
48    }
49  }"#;
50
51    println!("Attempting to deserialize...");
52    match facet_json::from_str::<Root>(json) {
53        Ok(root) => {
54            if let Some(items) = &root.container.items
55                && let Some(item) = items.get("a")
56            {
57                match &item.tagged {
58                    Tagged::TypeA { value, data } => {
59                        println!("value: {}", value);
60                        println!("data.y[0]: {}", data.y.first().unwrap_or(&0.0));
61
62                        if data.y.is_empty() || *data.y.first().unwrap_or(&0.0) == 0.0 {
63                            println!("BUG: Arc<Inner> not deserialized correctly!");
64                        } else {
65                            println!("SUCCESS: Arc<Inner> deserialized correctly!");
66                        }
67                    }
68                }
69            }
70        }
71        Err(e) => {
72            println!("Failed: {:?}", e);
73        }
74    }
75
76    // This produces access violation (running on windows)
77    println!("Attempting second deserialization...");
78    match facet_json::from_str::<Root>(json) {
79        Ok(_) => println!("Second deserialization succeeded"),
80        Err(e) => println!("Second deserialization failed: {:?}", e),
81    }
82}
examples/debug_2010.rs (line 35)
31fn main() {
32    // Simpler test - just Item directly
33    println!("=== Test 1: Item directly, tag first ===");
34    let json1 = r#"{"kind": "TypeB", "alpha": 1.0, "beta": 2.0, "extra": "test"}"#;
35    match facet_json::from_str::<Item>(json1) {
36        Ok(item) => println!("OK: {:?}", item),
37        Err(e) => println!("ERR: {:?}", e),
38    }
39
40    println!("\n=== Test 2: Item directly, tag in middle ===");
41    let json2 = r#"{"alpha": 1.0, "kind": "TypeB", "beta": 2.0, "extra": "test"}"#;
42    match facet_json::from_str::<Item>(json2) {
43        Ok(item) => println!("OK: {:?}", item),
44        Err(e) => println!("ERR: {:?}", e),
45    }
46
47    println!("\n=== Test 3: Item directly, tag last ===");
48    let json3 = r#"{"alpha": 1.0, "beta": 2.0, "extra": "test", "kind": "TypeB"}"#;
49    match facet_json::from_str::<Item>(json3) {
50        Ok(item) => println!("OK: {:?}", item),
51        Err(e) => println!("ERR: {:?}", e),
52    }
53
54    println!("\n=== Test 4: HashMap<String, Item>, tag first ===");
55    let json4 = r#"{"x": {"kind": "TypeB", "alpha": 1.0, "beta": 2.0, "extra": "test"}}"#;
56    match facet_json::from_str::<HashMap<String, Item>>(json4) {
57        Ok(map) => println!("OK: {:?}", map),
58        Err(e) => println!("ERR: {:?}", e),
59    }
60
61    println!("\n=== Test 5: HashMap<String, Item>, tag in middle ===");
62    let json5 = r#"{"x": {"alpha": 1.0, "kind": "TypeB", "beta": 2.0, "extra": "test"}}"#;
63    match facet_json::from_str::<HashMap<String, Item>>(json5) {
64        Ok(map) => println!("OK: {:?}", map),
65        Err(e) => println!("ERR: {:?}", e),
66    }
67
68    println!("\n=== Test 6: Full Outer struct, tag first ===");
69    let json6 = r#"{
70        "container": {
71            "items": {
72                "x": {
73                    "kind": "TypeB",
74                    "alpha": 1.0,
75                    "beta": 2.0,
76                    "extra": "test"
77                }
78            }
79        }
80    }"#;
81    match facet_json::from_str::<Outer>(json6) {
82        Ok(outer) => println!("OK: {:?}", outer),
83        Err(e) => println!("ERR: {:?}", e),
84    }
85
86    println!("\n=== Test 7: Full Outer struct, tag in middle ===");
87    let json7 = r#"{
88        "container": {
89            "items": {
90                "x": {
91                    "alpha": 1.0,
92                    "extra": "test",
93                    "kind": "TypeB",
94                    "beta": 2.0
95                }
96            }
97        }
98    }"#;
99    match facet_json::from_str::<Outer>(json7) {
100        Ok(outer) => println!("OK: {:?}", outer),
101        Err(e) => println!("ERR: {:?}", e),
102    }
103
104    // Narrow down - is it Option<HashMap> or just HashMap in Container?
105    println!("\n=== Test 8: Container directly, tag first ===");
106    let json8 =
107        r#"{"items": {"x": {"kind": "TypeB", "alpha": 1.0, "beta": 2.0, "extra": "test"}}}"#;
108    match facet_json::from_str::<Container>(json8) {
109        Ok(c) => println!("OK: {:?}", c),
110        Err(e) => println!("ERR: {:?}", e),
111    }
112
113    println!("\n=== Test 9: Container directly, tag in middle ===");
114    let json9 =
115        r#"{"items": {"x": {"alpha": 1.0, "kind": "TypeB", "beta": 2.0, "extra": "test"}}}"#;
116    match facet_json::from_str::<Container>(json9) {
117        Ok(c) => println!("OK: {:?}", c),
118        Err(e) => println!("ERR: {:?}", e),
119    }
120
121    // Without Option
122    #[derive(Clone, Debug, Facet, PartialEq)]
123    pub struct ContainerNoOption {
124        pub items: HashMap<String, Item>,
125    }
126
127    println!("\n=== Test 10: ContainerNoOption, tag first ===");
128    let json10 =
129        r#"{"items": {"x": {"kind": "TypeB", "alpha": 1.0, "beta": 2.0, "extra": "test"}}}"#;
130    match facet_json::from_str::<ContainerNoOption>(json10) {
131        Ok(c) => println!("OK: {:?}", c),
132        Err(e) => println!("ERR: {:?}", e),
133    }
134
135    println!("\n=== Test 11: ContainerNoOption, tag in middle ===");
136    let json11 =
137        r#"{"items": {"x": {"alpha": 1.0, "kind": "TypeB", "beta": 2.0, "extra": "test"}}}"#;
138    match facet_json::from_str::<ContainerNoOption>(json11) {
139        Ok(c) => println!("OK: {:?}", c),
140        Err(e) => println!("ERR: {:?}", e),
141    }
142
143    // Outer without Option
144    #[derive(Clone, Debug, Facet, PartialEq)]
145    pub struct OuterNoOption {
146        pub container: ContainerNoOption,
147    }
148
149    println!("\n=== Test 12: OuterNoOption, tag first ===");
150    let json12 = r#"{"container": {"items": {"x": {"kind": "TypeB", "alpha": 1.0, "beta": 2.0, "extra": "test"}}}}"#;
151    match facet_json::from_str::<OuterNoOption>(json12) {
152        Ok(o) => println!("OK: {:?}", o),
153        Err(e) => println!("ERR: {:?}", e),
154    }
155
156    println!("\n=== Test 13: OuterNoOption, tag in middle ===");
157    let json13 = r#"{"container": {"items": {"x": {"alpha": 1.0, "kind": "TypeB", "beta": 2.0, "extra": "test"}}}}"#;
158    match facet_json::from_str::<OuterNoOption>(json13) {
159        Ok(o) => println!("OK: {:?}", o),
160        Err(e) => println!("ERR: {:?}", e),
161    }
162
163    // Maybe it's specific to Outer wrapping Container with Option<HashMap>
164    // Let's try Outer2 wrapping Container (which has Option<HashMap>)
165    #[derive(Clone, Debug, Facet, PartialEq)]
166    pub struct Outer2 {
167        pub c: Container,
168    }
169
170    println!("\n=== Test 14: Outer2 with Container (Option<HashMap>), tag first ===");
171    let json14 =
172        r#"{"c": {"items": {"x": {"kind": "TypeB", "alpha": 1.0, "beta": 2.0, "extra": "test"}}}}"#;
173    match facet_json::from_str::<Outer2>(json14) {
174        Ok(o) => println!("OK: {:?}", o),
175        Err(e) => println!("ERR: {:?}", e),
176    }
177
178    println!("\n=== Test 15: Outer2 with Container (Option<HashMap>), tag in middle ===");
179    let json15 =
180        r#"{"c": {"items": {"x": {"alpha": 1.0, "kind": "TypeB", "beta": 2.0, "extra": "test"}}}}"#;
181    match facet_json::from_str::<Outer2>(json15) {
182        Ok(o) => println!("OK: {:?}", o),
183        Err(e) => println!("ERR: {:?}", e),
184    }
185}