1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
use std::{collections::BTreeMap, sync::Arc};
use serde::de;
use crate::ir::FieldValue;
mod deserializers;
#[cfg(test)]
mod tests;
/// Deserialize Trustfall query results into a Rust struct.
///
/// ```rust
/// # use std::{collections::BTreeMap, sync::Arc};
/// # use maplit::btreemap;
/// # use trustfall_core::ir::FieldValue;
/// #
/// # fn run_query() -> Result<Box<dyn Iterator<Item = BTreeMap<Arc<str>, FieldValue>>>, ()> {
/// # Ok(Box::new(vec![
/// # btreemap! {
/// # Arc::from("number") => FieldValue::Int64(42),
/// # Arc::from("text") => FieldValue::String("the answer to everything".to_string()),
/// # }
/// # ].into_iter()))
/// # }
///
/// use trustfall_core::TryIntoStruct;
///
/// #[derive(Debug, PartialEq, Eq, serde::Deserialize)]
/// struct Output {
/// number: i64,
/// text: String,
/// }
///
/// let results: Vec<_> = run_query()
/// .expect("bad query arguments")
/// .map(|v| v.try_into_struct().expect("struct definition did not match query result shape"))
/// .collect();
///
/// assert_eq!(
/// vec![
/// Output {
/// number: 42,
/// text: "the answer to everything".to_string(),
/// },
/// ],
/// results,
/// );
/// ```
pub trait TryIntoStruct {
type Error;
fn try_into_struct<S: for<'de> de::Deserialize<'de>>(self) -> Result<S, Self::Error>;
}
impl TryIntoStruct for BTreeMap<Arc<str>, FieldValue> {
type Error = deserializers::Error;
fn try_into_struct<S: for<'de> de::Deserialize<'de>>(self) -> Result<S, deserializers::Error> {
let deserializer = deserializers::QueryResultDeserializer::new(self);
S::deserialize(deserializer)
}
}