diff options
author | Nadrieril | 2020-10-24 15:37:52 +0100 |
---|---|---|
committer | GitHub | 2020-10-24 15:37:52 +0100 |
commit | d9e42ea1fe16fc9f16a390f2dac2713e691b2700 (patch) | |
tree | e5bae5c7a70f2c3721baf2e8a4c3683c5dfb71dc | |
parent | 41b303c00392571fe8c862041b811f7716e38b57 (diff) | |
parent | 34a4727366e8efb4f9d51c9f636ebcda580173b0 (diff) |
Merge pull request #183 from io12/pub-simple-value
Make SimpleValue public and add from_simple_value()
Diffstat (limited to '')
-rw-r--r-- | serde_dhall/src/deserialize.rs | 47 | ||||
-rw-r--r-- | serde_dhall/src/lib.rs | 4 | ||||
-rw-r--r-- | serde_dhall/src/value.rs | 85 |
3 files changed, 130 insertions, 6 deletions
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<T> 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<T>(v: SimpleValue) -> Result<T> +where + T: serde::de::DeserializeOwned, +{ + T::deserialize(Deserializer(Cow::Owned(v))) +} + impl<T> 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<SimpleType>, } -/// 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<u64>, +/// } +/// +/// 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<Box<SimpleValue>>), + /// A list of values - `[a, b, c, d, e]` List(Vec<SimpleValue>), + /// A record value - `{ k1 = v1, k2 = v2 }` Record(BTreeMap<String, SimpleValue>), + /// A union value (both the name of the variant and the variant's value) - `Left e` Union(String, Option<Box<SimpleValue>>), } |