summaryrefslogtreecommitdiff
path: root/serde_dhall
diff options
context:
space:
mode:
authorNadrieril2020-03-22 21:20:58 +0000
committerNadrieril2020-03-31 21:45:31 +0100
commit1a98b506055779e1a60558d9c5a56b071b3d61a0 (patch)
tree1ec11648ed9e3c503c6f4f06307c3541af648a23 /serde_dhall
parent196491a37a9ab2869ab6d76e1417a85a9e033dd4 (diff)
Reorganize API and internals of serde_dhall a bit
Diffstat (limited to 'serde_dhall')
-rw-r--r--serde_dhall/src/deserialize.rs (renamed from serde_dhall/src/serde.rs)21
-rw-r--r--serde_dhall/src/lib.rs80
-rw-r--r--serde_dhall/src/shortcuts.rs100
-rw-r--r--serde_dhall/src/simple.rs2
-rw-r--r--serde_dhall/src/value.rs2
-rw-r--r--serde_dhall/tests/de.rs6
-rw-r--r--serde_dhall/tests/version_numbers.rs5
7 files changed, 144 insertions, 72 deletions
diff --git a/serde_dhall/src/serde.rs b/serde_dhall/src/deserialize.rs
index 717450a..75a08a9 100644
--- a/serde_dhall/src/serde.rs
+++ b/serde_dhall/src/deserialize.rs
@@ -1,15 +1,28 @@
-use std::borrow::Cow;
-
use serde::de::value::{
MapAccessDeserializer, MapDeserializer, SeqDeserializer,
};
+use std::borrow::Cow;
use dhall::syntax::NumKind;
use crate::simple::{ValKind, Value as SimpleValue};
-use crate::{Deserialize, Error, Result, Value};
+use crate::{Error, Result, Value};
+
+pub trait Sealed {}
+
+/// A data structure that can be deserialized from a Dhall expression
+///
+/// This is automatically implemented for any type that [serde][serde]
+/// can deserialize.
+///
+/// This trait cannot be implemented manually.
+pub trait Deserialize: Sealed + Sized {
+ #[doc(hidden)]
+ /// See [serde_dhall::from_str][crate::from_str]
+ fn from_dhall(v: &Value) -> Result<Self>;
+}
-impl<'a, T> crate::sealed::Sealed for T where T: serde::Deserialize<'a> {}
+impl<'a, T> Sealed for T where T: serde::Deserialize<'a> {}
struct Deserializer<'a>(Cow<'a, SimpleValue>);
diff --git a/serde_dhall/src/lib.rs b/serde_dhall/src/lib.rs
index 4250882..5ee1cf6 100644
--- a/serde_dhall/src/lib.rs
+++ b/serde_dhall/src/lib.rs
@@ -1,4 +1,6 @@
#![doc(html_root_url = "https://docs.rs/serde_dhall/0.4.0")]
+// #![warn(missing_docs)]
+// #![warn(missing_doc_code_examples)]
//! [Dhall][dhall] is a programmable configuration language that provides a non-repetitive
//! alternative to JSON and YAML.
//!
@@ -107,7 +109,7 @@
//! can let Rust infer it for you.
//!
//! To provide a type written in Dhall, first parse it into a [`simple::Type`](simple/struct.Type.html), then
-//! pass it to [`from_str_check_type`](fn.from_str_check_type.html).
+//! pass it to [`from_str_manual_type`](fn.from_str_manual_type.html).
//!
//! ```rust
//! # fn main() -> serde_dhall::Result<()> {
@@ -124,7 +126,7 @@
//! // Deserialize the data to a Rust type. This checks that
//! // the data matches the provided type.
//! let deserialized_map: HashMap<String, usize> =
-//! serde_dhall::from_str_check_type(point_data, &point_type)?;
+//! serde_dhall::from_str_manual_type(point_data, &point_type)?;
//!
//! let mut expected_map = HashMap::new();
//! expected_map.insert("x".to_string(), 1);
@@ -153,13 +155,13 @@
//! let data = "{ x = 1, y = 1 + 1 }";
//!
//! // Convert the Dhall string to a Point.
-//! let point: Point = serde_dhall::from_str_auto_type(data)?;
+//! let point: Point = serde_dhall::from_str_static_type(data)?;
//! assert_eq!(point.x, 1);
//! assert_eq!(point.y, 2);
//!
//! // Invalid data fails the type validation
//! let invalid_data = "{ x = 1, z = 0.3 }";
-//! assert!(serde_dhall::from_str_auto_type::<Point>(invalid_data).is_err());
+//! assert!(serde_dhall::from_str_static_type::<Point>(invalid_data).is_err());
//! # Ok(())
//! # }
//! ```
@@ -171,72 +173,26 @@
#[cfg(doctest)]
doc_comment::doctest!("../../README.md");
-mod error;
/// Finer-grained control over deserializing Dhall
pub mod options;
-mod serde;
-/// Serde-compatible values and their type
+/// Serde-compatible Dhall values and their type
pub mod simple;
-mod static_type;
/// Arbitrary Dhall values
pub mod value;
-pub use crate::simple::{Type as SimpleType, Value as SimpleValue};
+mod deserialize;
+mod error;
+/// Common patterns made easier
+mod shortcuts;
+mod static_type;
+
#[doc(hidden)]
pub use dhall_proc_macros::StaticType;
+
+pub use deserialize::Deserialize;
+pub(crate) use deserialize::Sealed;
pub use error::{Error, Result};
+pub use shortcuts::{from_str, from_str_manual_type, from_str_static_type};
+pub use simple::{Type as SimpleType, Value as SimpleValue};
pub use static_type::StaticType;
pub use value::Value;
-
-pub(crate) mod sealed {
- pub trait Sealed {}
-}
-
-/// A data structure that can be deserialized from a Dhall expression
-///
-/// This is automatically implemented for any type that [serde][serde]
-/// can deserialize.
-///
-/// This trait cannot be implemented manually.
-pub trait Deserialize: sealed::Sealed + Sized {
- /// See [serde_dhall::from_str][crate::from_str]
- fn from_dhall(v: &Value) -> Result<Self>;
-}
-
-/// Deserialize an instance of type `T` from a string of Dhall text.
-///
-/// This will recursively resolve all imports in the expression, and
-/// typecheck it before deserialization. Relative imports will be resolved relative to the
-/// provided file. More control over this process is not yet available
-/// but will be in a coming version of this crate.
-pub fn from_str<T>(s: &str) -> Result<T>
-where
- T: Deserialize,
-{
- options::from_str(s).parse()
-}
-
-/// Deserialize an instance of type `T` from a string of Dhall text,
-/// additionally checking that it matches the supplied type.
-///
-/// Like [from_str], but this additionally checks that
-/// the type of the provided expression matches the supplied type.
-pub fn from_str_check_type<T>(s: &str, ty: &simple::Type) -> Result<T>
-where
- T: Deserialize,
-{
- options::from_str(s).type_annotation(ty).parse()
-}
-
-/// Deserialize an instance of type `T` from a string of Dhall text,
-/// additionally checking that it matches the type of `T`.
-///
-/// Like [from_str], but this additionally checks that
-/// the type of the provided expression matches the output type `T`. The [StaticType] trait
-/// captures Rust types that are valid Dhall types.
-pub fn from_str_auto_type<T>(s: &str) -> Result<T>
-where
- T: Deserialize + StaticType,
-{
- options::from_str(s).static_type_annotation().parse()
-}
diff --git a/serde_dhall/src/shortcuts.rs b/serde_dhall/src/shortcuts.rs
new file mode 100644
index 0000000..1fb1032
--- /dev/null
+++ b/serde_dhall/src/shortcuts.rs
@@ -0,0 +1,100 @@
+use crate::error::Result;
+use crate::options;
+use crate::simple::Type as SimpleType;
+use crate::static_type::StaticType;
+use crate::Deserialize;
+
+/// Deserialize an instance of type `T` from a string of Dhall text.
+///
+/// This will recursively resolve all imports in the expression, and typecheck it before
+/// deserialization. Relative imports will be resolved relative to the current directory.
+/// See [`options`][`options`] for more control over this process.
+///
+/// For additional type safety, prefer [`from_str_static_type`][`from_str_static_type`] or
+/// [`from_str_manual_type`][`from_str_manual_type`].
+///
+///
+/// # Example
+///
+/// ```rust
+/// # fn main() -> serde_dhall::Result<()> {
+/// use serde::Deserialize;
+///
+/// #[derive(Debug, Deserialize)]
+/// struct Point {
+/// x: u64,
+/// y: u64,
+/// }
+///
+/// // Some Dhall data
+/// let data = "{ x = 1, y = 1 + 1 } : { x: Natural, y: Natural }";
+///
+/// // Convert the Dhall string to a Point.
+/// let point: Point = serde_dhall::from_str(data)?;
+/// assert_eq!(point.x, 1);
+/// assert_eq!(point.y, 2);
+///
+/// # Ok(())
+/// # }
+/// ```
+///
+/// [`options`]: options/index.html
+/// [`from_str_manual_type`]: fn.from_str_manual_type.html
+/// [`from_str_static_type`]: fn.from_str_static_type.html
+pub fn from_str<T>(s: &str) -> Result<T>
+where
+ T: Deserialize,
+{
+ options::from_str(s).parse()
+}
+
+/// Deserialize an instance of type `T` from a string of Dhall text,
+/// additionally checking that it matches the supplied type.
+///
+/// Like [`from_str`], but this additionally checks that
+/// the type of the provided expression matches the supplied type.
+///
+/// ```rust
+/// # fn main() -> serde_dhall::Result<()> {
+/// use serde_dhall::simple::Type;
+/// use std::collections::HashMap;
+///
+/// // Parse a Dhall type
+/// let point_type_str = "{ x: Natural, y: Natural }";
+/// let point_type: Type = serde_dhall::from_str(point_type_str)?;
+///
+/// // Some Dhall data
+/// let point_data = "{ x = 1, y = 1 + 1 }";
+///
+/// // Deserialize the data to a Rust type. This checks that
+/// // the data matches the provided type.
+/// let deserialized_map: HashMap<String, usize> =
+/// serde_dhall::from_str_manual_type(point_data, &point_type)?;
+///
+/// let mut expected_map = HashMap::new();
+/// expected_map.insert("x".to_string(), 1);
+/// expected_map.insert("y".to_string(), 2);
+///
+/// assert_eq!(deserialized_map, expected_map);
+/// # Ok(())
+/// # }
+/// ```
+pub fn from_str_manual_type<T>(s: &str, ty: &SimpleType) -> Result<T>
+where
+ T: Deserialize,
+{
+ options::from_str(s).type_annotation(ty).parse()
+}
+
+/// Deserialize an instance of type `T` from a string of Dhall text,
+/// additionally checking that it matches the type of `T`.
+///
+/// Like [from_str], but this additionally checks that
+/// the type of the provided expression matches the output type `T`. The [StaticType] trait
+/// captures Rust types that are valid Dhall types.
+pub fn from_str_static_type<T>(s: &str) -> Result<T>
+where
+ T: Deserialize + StaticType,
+{
+ options::from_str(s).static_type_annotation().parse()
+}
diff --git a/serde_dhall/src/simple.rs b/serde_dhall/src/simple.rs
index 4cd4ab7..95642bd 100644
--- a/serde_dhall/src/simple.rs
+++ b/serde_dhall/src/simple.rs
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use dhall::semantics::{Hir, HirKind, Nir, NirKind};
use dhall::syntax::{Builtin, ExprKind, NumKind, Span};
-use crate::{sealed::Sealed, Deserialize, Error, Result};
+use crate::{Deserialize, Error, Result, Sealed};
/// A simple value of the kind that can be encoded/decoded with serde
#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/serde_dhall/src/value.rs b/serde_dhall/src/value.rs
index d4ded90..a119028 100644
--- a/serde_dhall/src/value.rs
+++ b/serde_dhall/src/value.rs
@@ -2,7 +2,7 @@ use dhall::semantics::{Hir, Nir};
use dhall::syntax::Expr;
use crate::simple::{Type as SimpleType, Value as SimpleValue};
-use crate::{sealed::Sealed, Deserialize, Error};
+use crate::{Deserialize, Error, Sealed};
/// An arbitrary Dhall value.
#[derive(Debug, Clone)]
diff --git a/serde_dhall/tests/de.rs b/serde_dhall/tests/de.rs
index b201e4f..f28b265 100644
--- a/serde_dhall/tests/de.rs
+++ b/serde_dhall/tests/de.rs
@@ -1,10 +1,10 @@
use serde::Deserialize;
-use serde_dhall::{from_str, from_str_auto_type, StaticType};
+use serde_dhall::{from_str, from_str_static_type, StaticType};
#[test]
fn test_de_typed() {
fn parse<T: serde_dhall::Deserialize + StaticType>(s: &str) -> T {
- from_str_auto_type(s).unwrap()
+ from_str_static_type(s).unwrap()
}
assert_eq!(parse::<bool>("True"), true);
@@ -52,7 +52,7 @@ fn test_de_typed() {
}
assert_eq!(parse::<Baz>("< X | Y: Integer >.X"), Baz::X);
- assert!(from_str_auto_type::<Baz>("< X | Y: Integer >.Y").is_err());
+ assert!(from_str_static_type::<Baz>("< X | Y: Integer >.Y").is_err());
}
#[test]
diff --git a/serde_dhall/tests/version_numbers.rs b/serde_dhall/tests/version_numbers.rs
index 97254a9..8307e47 100644
--- a/serde_dhall/tests/version_numbers.rs
+++ b/serde_dhall/tests/version_numbers.rs
@@ -10,5 +10,8 @@ fn test_html_root_url() {
#[test]
fn test_readme_mentions_version() {
- version_sync::assert_contains_regex!("../README.md", "^#### \\[{version}\\]");
+ version_sync::assert_contains_regex!(
+ "../README.md",
+ "^#### \\[{version}\\]"
+ );
}