summaryrefslogtreecommitdiff
path: root/serde_dhall/src
diff options
context:
space:
mode:
Diffstat (limited to 'serde_dhall/src')
-rw-r--r--serde_dhall/src/error.rs30
-rw-r--r--serde_dhall/src/lib.rs264
-rw-r--r--serde_dhall/src/serde.rs4
-rw-r--r--serde_dhall/src/simple.rs81
4 files changed, 176 insertions, 203 deletions
diff --git a/serde_dhall/src/error.rs b/serde_dhall/src/error.rs
new file mode 100644
index 0000000..91a0b94
--- /dev/null
+++ b/serde_dhall/src/error.rs
@@ -0,0 +1,30 @@
+use dhall::error::Error as DhallError;
+
+pub type Result<T> = std::result::Result<T, Error>;
+
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum Error {
+ Dhall(DhallError),
+ Deserialize(String),
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ Error::Dhall(err) => write!(f, "{}", err),
+ Error::Deserialize(err) => write!(f, "{}", err),
+ }
+ }
+}
+
+impl std::error::Error for Error {}
+
+impl serde::de::Error for Error {
+ fn custom<T>(msg: T) -> Self
+ where
+ T: std::fmt::Display,
+ {
+ Error::Deserialize(msg.to_string())
+ }
+}
diff --git a/serde_dhall/src/lib.rs b/serde_dhall/src/lib.rs
index 134528c..15f45ce 100644
--- a/serde_dhall/src/lib.rs
+++ b/serde_dhall/src/lib.rs
@@ -22,7 +22,7 @@
//! This could mean a common Rust type like `HashMap`:
//!
//! ```rust
-//! # fn main() -> serde_dhall::de::Result<()> {
+//! # fn main() -> serde_dhall::Result<()> {
//! use std::collections::HashMap;
//!
//! // Some Dhall data
@@ -43,7 +43,7 @@
//! or a custom datatype, using serde's `derive` mechanism:
//!
//! ```rust
-//! # fn main() -> serde_dhall::de::Result<()> {
+//! # fn main() -> serde_dhall::Result<()> {
//! use serde::Deserialize;
//!
//! #[derive(Debug, Deserialize)]
@@ -110,8 +110,8 @@
//! pass it to [`from_str_check_type`][from_str_check_type].
//!
//! ```rust
-//! # fn main() -> serde_dhall::de::Result<()> {
-//! use serde_dhall::Type;
+//! # fn main() -> serde_dhall::Result<()> {
+//! use serde_dhall::simple::Type;
//! use std::collections::HashMap;
//!
//! // Parse a Dhall type
@@ -138,7 +138,7 @@
//! You can also let Rust infer the appropriate Dhall type, using the [StaticType] trait.
//!
//! ```rust
-//! # fn main() -> serde_dhall::de::Result<()> {
+//! # fn main() -> serde_dhall::Result<()> {
//! use serde::Deserialize;
//! use serde_dhall::StaticType;
//!
@@ -167,215 +167,77 @@
//! [serde]: https://docs.serde.rs/serde/
//! [serde::Deserialize]: https://docs.serde.rs/serde/trait.Deserialize.html
+mod error;
mod serde;
+pub mod simple;
mod static_type;
-#[doc(inline)]
-pub use de::{from_str, from_str_auto_type, from_str_check_type};
#[doc(hidden)]
pub use dhall_proc_macros::StaticType;
+pub use error::{Error, Result};
pub use static_type::StaticType;
-#[doc(inline)]
-pub use ty::Type;
-#[doc(inline)]
-pub use value::Value;
-// A Dhall value.
-#[doc(hidden)]
-pub mod value {
- use dhall::SimpleValue;
-
- use super::de::Error;
-
- /// A Dhall value. This is a wrapper around [`dhall::SimpleValue`].
- #[derive(Debug, Clone, PartialEq, Eq)]
- pub struct Value(SimpleValue);
+use simple::Type;
- impl Value {
- pub fn into_simple_value(self) -> SimpleValue {
- self.0
- }
- }
-
- impl super::de::sealed::Sealed for Value {}
-
- impl super::de::Deserialize for Value {
- fn from_dhall(v: &dhall::Value) -> super::de::Result<Self> {
- let sval = v.to_simple_value().ok_or_else(|| {
- Error::Deserialize(format!(
- "this cannot be deserialized into a simple type: {}",
- v
- ))
- })?;
- Ok(Value(sval))
- }
- }
+pub(crate) mod sealed {
+ pub trait Sealed {}
}
-// A Dhall type.
-#[doc(hidden)]
-pub mod ty {
- use dhall::{STyKind, SimpleType};
-
- use super::de::Error;
-
- /// A Dhall type. This is a wrapper around [`dhall::SimpleType`].
- #[derive(Debug, Clone, PartialEq, Eq)]
- pub struct Type(SimpleType);
-
- impl Type {
- pub fn into_simple_type(self) -> SimpleType {
- self.0
- }
- pub fn to_dhall_value(&self) -> dhall::Value {
- self.0.to_value()
- }
-
- pub(crate) fn from_simple_type(ty: SimpleType) -> Self {
- Type(ty)
- }
- pub(crate) fn from_stykind(k: STyKind) -> Self {
- Type(SimpleType::new(k))
- }
- pub(crate) fn make_optional_type(t: Type) -> Self {
- Type::from_stykind(STyKind::Optional(t.0))
- }
- pub(crate) fn make_list_type(t: Type) -> Self {
- Type::from_stykind(STyKind::List(t.0))
- }
- // Made public for the StaticType derive macro
- #[doc(hidden)]
- pub fn make_record_type(
- kts: impl Iterator<Item = (String, Type)>,
- ) -> Self {
- Type::from_stykind(STyKind::Record(
- kts.map(|(k, t)| (k, t.0)).collect(),
- ))
- }
- #[doc(hidden)]
- pub fn make_union_type(
- kts: impl Iterator<Item = (String, Option<Type>)>,
- ) -> Self {
- Type::from_stykind(STyKind::Union(
- kts.map(|(k, t)| (k, t.map(|t| t.0))).collect(),
- ))
- }
- }
-
- impl super::de::sealed::Sealed for Type {}
-
- impl super::de::Deserialize for Type {
- fn from_dhall(v: &dhall::Value) -> super::de::Result<Self> {
- let sty = v.to_simple_type().ok_or_else(|| {
- Error::Deserialize(format!(
- "this cannot be deserialized into a simple type: {}",
- v
- ))
- })?;
- Ok(Type(sty))
- }
- }
+/// 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: &dhall::Value) -> Result<Self>;
}
-/// Deserialize Dhall data to a Rust data structure.
-pub mod de {
- use super::StaticType;
- use super::Type;
- pub use error::{Error, Result};
-
- mod error {
- use dhall::error::Error as DhallError;
-
- pub type Result<T> = std::result::Result<T, Error>;
-
- #[derive(Debug)]
- #[non_exhaustive]
- pub enum Error {
- Dhall(DhallError),
- Deserialize(String),
- }
-
- impl std::fmt::Display for Error {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- match self {
- Error::Dhall(err) => write!(f, "{}", err),
- Error::Deserialize(err) => write!(f, "{}", err),
- }
- }
- }
-
- impl std::error::Error for Error {}
-
- impl serde::de::Error for Error {
- fn custom<T>(msg: T) -> Self
- where
- T: std::fmt::Display,
- {
- Error::Deserialize(msg.to_string())
- }
- }
- }
-
- 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: &dhall::Value) -> Result<Self>;
- }
-
- fn from_str_with_annot<T>(s: &str, ty: Option<&Type>) -> Result<T>
- where
- T: Deserialize,
- {
- let ty = ty.map(|ty| ty.to_dhall_value());
- let val = dhall::Value::from_str_with_annot(s, ty.as_ref())
- .map_err(Error::Dhall)?;
- T::from_dhall(&val)
- }
+fn from_str_with_annot<T>(s: &str, ty: Option<&Type>) -> Result<T>
+where
+ T: Deserialize,
+{
+ let ty = ty.map(|ty| ty.to_dhall_value());
+ let val = dhall::Value::from_str_with_annot(s, ty.as_ref())
+ .map_err(Error::Dhall)?;
+ T::from_dhall(&val)
+}
- /// 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,
- {
- from_str_with_annot(s, None)
- }
+/// 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,
+{
+ from_str_with_annot(s, None)
+}
- /// 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: &Type) -> Result<T>
- where
- T: Deserialize,
- {
- from_str_with_annot(s, Some(ty))
- }
+/// 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: &Type) -> Result<T>
+where
+ T: Deserialize,
+{
+ from_str_with_annot(s, Some(ty))
+}
- /// 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,
- {
- from_str_check_type(s, &<T as StaticType>::static_type())
- }
+/// 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,
+{
+ from_str_check_type(s, &<T as StaticType>::static_type())
}
diff --git a/serde_dhall/src/serde.rs b/serde_dhall/src/serde.rs
index e06fb3d..d144abf 100644
--- a/serde_dhall/src/serde.rs
+++ b/serde_dhall/src/serde.rs
@@ -7,9 +7,9 @@ use serde::de::value::{
use dhall::syntax::NumKind;
use dhall::{SValKind, SimpleValue};
-use crate::de::{Deserialize, Error, Result};
+use crate::{Deserialize, Error, Result};
-impl<'a, T> crate::de::sealed::Sealed for T where T: serde::Deserialize<'a> {}
+impl<'a, T> crate::sealed::Sealed for T where T: serde::Deserialize<'a> {}
struct Deserializer<'a>(Cow<'a, SimpleValue>);
diff --git a/serde_dhall/src/simple.rs b/serde_dhall/src/simple.rs
new file mode 100644
index 0000000..93364a0
--- /dev/null
+++ b/serde_dhall/src/simple.rs
@@ -0,0 +1,81 @@
+use super::Error;
+use dhall::{STyKind, SimpleType, SimpleValue};
+
+/// A Dhall value. This is a wrapper around [`dhall::SimpleValue`].
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Value(SimpleValue);
+
+impl Value {
+ pub fn into_simple_value(self) -> SimpleValue {
+ self.0
+ }
+}
+
+/// A Dhall type. This is a wrapper around [`dhall::SimpleType`].
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Type(SimpleType);
+
+impl Type {
+ pub fn into_simple_type(self) -> SimpleType {
+ self.0
+ }
+ pub fn to_dhall_value(&self) -> dhall::Value {
+ self.0.to_value()
+ }
+
+ pub(crate) fn from_simple_type(ty: SimpleType) -> Self {
+ Type(ty)
+ }
+ pub(crate) fn from_stykind(k: STyKind) -> Self {
+ Type(SimpleType::new(k))
+ }
+ pub(crate) fn make_optional_type(t: Type) -> Self {
+ Type::from_stykind(STyKind::Optional(t.0))
+ }
+ pub(crate) fn make_list_type(t: Type) -> Self {
+ Type::from_stykind(STyKind::List(t.0))
+ }
+ // Made public for the StaticType derive macro
+ #[doc(hidden)]
+ pub fn make_record_type(kts: impl Iterator<Item = (String, Type)>) -> Self {
+ Type::from_stykind(STyKind::Record(
+ kts.map(|(k, t)| (k, t.0)).collect(),
+ ))
+ }
+ #[doc(hidden)]
+ pub fn make_union_type(
+ kts: impl Iterator<Item = (String, Option<Type>)>,
+ ) -> Self {
+ Type::from_stykind(STyKind::Union(
+ kts.map(|(k, t)| (k, t.map(|t| t.0))).collect(),
+ ))
+ }
+}
+
+impl super::sealed::Sealed for Value {}
+
+impl super::Deserialize for Value {
+ fn from_dhall(v: &dhall::Value) -> super::Result<Self> {
+ let sval = v.to_simple_value().ok_or_else(|| {
+ Error::Deserialize(format!(
+ "this cannot be deserialized into a simple type: {}",
+ v
+ ))
+ })?;
+ Ok(Value(sval))
+ }
+}
+
+impl super::sealed::Sealed for Type {}
+
+impl super::Deserialize for Type {
+ fn from_dhall(v: &dhall::Value) -> super::Result<Self> {
+ let sty = v.to_simple_type().ok_or_else(|| {
+ Error::Deserialize(format!(
+ "this cannot be deserialized into a simple type: {}",
+ v
+ ))
+ })?;
+ Ok(Type(sty))
+ }
+}