From 34a4727366e8efb4f9d51c9f636ebcda580173b0 Mon Sep 17 00:00:00 2001 From: Benjamin Levy Date: Sat, 24 Oct 2020 04:24:21 -0400 Subject: Make SimpleValue public and add from_simple_value() --- serde_dhall/src/deserialize.rs | 47 ++++++++++++++++++++++- serde_dhall/src/lib.rs | 4 +- serde_dhall/src/value.rs | 85 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 130 insertions(+), 6 deletions(-) (limited to 'serde_dhall/src') diff --git a/serde_dhall/src/deserialize.rs b/serde_dhall/src/deserialize.rs index 92be2e9..6d3aab8 100644 --- a/serde_dhall/src/deserialize.rs +++ b/serde_dhall/src/deserialize.rs @@ -45,6 +45,51 @@ impl Sealed for T where T: serde::de::DeserializeOwned {} struct Deserializer<'a>(Cow<'a, SimpleValue>); +/// Deserialize a Rust value from a Dhall [`SimpleValue`]. +/// +/// # Example +/// +/// ```rust +/// # fn main() -> serde_dhall::Result<()> { +/// use std::collections::BTreeMap; +/// use serde::Deserialize; +/// +/// // We use serde's derive feature +/// #[derive(Deserialize)] +/// struct Point { +/// x: u64, +/// y: u64, +/// } +/// +/// // Some Dhall data +/// let mut data = BTreeMap::new(); +/// data.insert( +/// "x".to_string(), +/// serde_dhall::SimpleValue::Num(serde_dhall::NumKind::Natural(1)) +/// ); +/// data.insert( +/// "y".to_string(), +/// serde_dhall::SimpleValue::Num(serde_dhall::NumKind::Natural(2)) +/// ); +/// let data = serde_dhall::SimpleValue::Record(data); +/// +/// // Parse the Dhall value as a Point. +/// let point: Point = serde_dhall::from_simple_value(data)?; +/// +/// assert_eq!(point.x, 1); +/// assert_eq!(point.y, 2); +/// # Ok(()) +/// # } +/// ``` +/// +/// [`SimpleValue`]: enum.SimpleValue.html +pub fn from_simple_value(v: SimpleValue) -> Result +where + T: serde::de::DeserializeOwned, +{ + T::deserialize(Deserializer(Cow::Owned(v))) +} + impl FromDhall for T where T: serde::de::DeserializeOwned, @@ -56,7 +101,7 @@ where v ))) })?; - T::deserialize(Deserializer(Cow::Owned(sval))) + from_simple_value(sval) } } diff --git a/serde_dhall/src/lib.rs b/serde_dhall/src/lib.rs index ca3c265..73d74be 100644 --- a/serde_dhall/src/lib.rs +++ b/serde_dhall/src/lib.rs @@ -176,10 +176,10 @@ mod value; #[doc(hidden)] pub use dhall_proc_macros::StaticType; -pub use deserialize::FromDhall; pub(crate) use deserialize::Sealed; +pub use deserialize::{from_simple_value, FromDhall}; pub(crate) use error::ErrorKind; pub use error::{Error, Result}; pub use options::{from_file, from_str, Deserializer}; pub use static_type::StaticType; -pub use value::{SimpleType, Value}; +pub use value::{NumKind, SimpleType, SimpleValue, Value}; diff --git a/serde_dhall/src/value.rs b/serde_dhall/src/value.rs index b26985b..79ba75a 100644 --- a/serde_dhall/src/value.rs +++ b/serde_dhall/src/value.rs @@ -3,7 +3,8 @@ use std::collections::{BTreeMap, HashMap}; use dhall::builtins::Builtin; use dhall::operations::OpKind; use dhall::semantics::{Hir, HirKind, Nir, NirKind}; -use dhall::syntax::{Expr, ExprKind, NumKind, Span}; +pub use dhall::syntax::NumKind; +use dhall::syntax::{Expr, ExprKind, Span}; use crate::{Error, ErrorKind, FromDhall, Result, Sealed}; @@ -19,14 +20,92 @@ pub struct Value { as_simple_ty: Option, } -/// A simple value of the kind that can be decoded with serde +/// A value of the kind that can be decoded by `serde_dhall`, e.g. `{ x = True, y = [1, 2, 3] }`. +/// This can be obtained with [`from_str()`] or [`from_file()`]. +/// It can also be deserialized into Rust types with [`from_simple_value()`]. +/// +/// # Examples +/// +/// ```rust +/// # fn main() -> serde_dhall::Result<()> { +/// use std::collections::BTreeMap; +/// use serde::Deserialize; +/// use serde_dhall::{from_simple_value, NumKind, SimpleValue}; +/// +/// #[derive(Debug, PartialEq, Eq, Deserialize)] +/// struct Foo { +/// x: bool, +/// y: Vec, +/// } +/// +/// let value: SimpleValue = +/// serde_dhall::from_str("{ x = True, y = [1, 2, 3] }").parse()?; +/// +/// assert_eq!( +/// value, +/// SimpleValue::Record({ +/// let mut r = BTreeMap::new(); +/// r.insert( +/// "x".to_string(), +/// SimpleValue::Num(NumKind::Bool(true)) +/// ); +/// r.insert( +/// "y".to_string(), +/// SimpleValue::List(vec![ +/// SimpleValue::Num(NumKind::Natural(1)), +/// SimpleValue::Num(NumKind::Natural(2)), +/// SimpleValue::Num(NumKind::Natural(3)), +/// ]) +/// ); +/// r +/// }) +/// ); +/// +/// let foo: Foo = from_simple_value(value)?; +/// +/// assert_eq!( +/// foo, +/// Foo { +/// x: true, +/// y: vec![1, 2, 3] +/// } +/// ); +/// # Ok(()) +/// # } +/// ``` +/// +/// ```rust +/// # fn main() -> serde_dhall::Result<()> { +/// use std::collections::BTreeMap; +/// use serde_dhall::{NumKind, SimpleValue}; +/// +/// let value: SimpleValue = +/// serde_dhall::from_str("{ x = 1, y = 2 }").parse()?; +/// +/// let mut map = BTreeMap::new(); +/// map.insert("x".to_string(), SimpleValue::Num(NumKind::Natural(1))); +/// map.insert("y".to_string(), SimpleValue::Num(NumKind::Natural(2))); +/// assert_eq!(value, SimpleValue::Record(map)); +/// # Ok(()) +/// # } +/// ``` +/// +/// [`from_str()`]: fn.from_str.html +/// [`from_file()`]: fn.from_file.html +/// [`from_simple_value()`]: fn.from_simple_value.html #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum SimpleValue { +pub enum SimpleValue { + /// Numbers and booleans - `True`, `1`, `+2`, `3.24` Num(NumKind), + /// A string of text - `"Hello world!"` Text(String), + /// An optional value - `Some e`, `None` Optional(Option>), + /// A list of values - `[a, b, c, d, e]` List(Vec), + /// A record value - `{ k1 = v1, k2 = v2 }` Record(BTreeMap), + /// A union value (both the name of the variant and the variant's value) - `Left e` Union(String, Option>), } -- cgit v1.2.3