summaryrefslogtreecommitdiff
path: root/serde_dhall
diff options
context:
space:
mode:
authorBenjamin Levy2020-10-24 04:24:21 -0400
committerBenjamin Levy2020-10-24 04:24:21 -0400
commit34a4727366e8efb4f9d51c9f636ebcda580173b0 (patch)
treee5bae5c7a70f2c3721baf2e8a4c3683c5dfb71dc /serde_dhall
parent41b303c00392571fe8c862041b811f7716e38b57 (diff)
Make SimpleValue public and add from_simple_value()
Diffstat (limited to 'serde_dhall')
-rw-r--r--serde_dhall/src/deserialize.rs47
-rw-r--r--serde_dhall/src/lib.rs4
-rw-r--r--serde_dhall/src/value.rs85
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>>),
}