From 85e2e8ee5e83dadd05b6974ba6c951350cb97a61 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 21 Mar 2020 21:30:30 +0000 Subject: Introduce option builder --- serde_dhall/src/options.rs | 138 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 serde_dhall/src/options.rs (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs new file mode 100644 index 0000000..542804b --- /dev/null +++ b/serde_dhall/src/options.rs @@ -0,0 +1,138 @@ +use std::path::{Path, PathBuf}; + +use dhall::Parsed; + +use crate::simple::Type as SimpleType; +use crate::{Deserialize, Error, Result, StaticType, Value}; + +#[derive(Debug, Clone)] +enum Source<'a> { + Str(&'a str), + File(PathBuf), + // Url(&'a str), +} + +/// Options and flags which can be used to configure how a dhall value is read. +/// +/// This builder exposes the ability to configure how a value is deserialized and what operations +/// are permitted during evaluation. The functions in the crate root are aliases for +/// commonly used options using this builder. +/// +/// Generally speaking, when using `Options`, you'll create it with `from_str` or `from_file`, then +/// chain calls to methods to set each option, then call `parse`. This will give you a +/// `serde_dhall::Result` where `T` a deserializable type of your choice. +/// +/// # Examples +/// +/// Reading from a file: +/// +/// ```no_run +/// # fn main() -> serde_dhall::Result<()> { +/// use serde_dhall::options; +/// +/// let data = options::from_file("foo.dhall").parse()?; +/// # Ok(()) +/// # } +/// ``` +/// +/// Reading from a file and checking the value against a provided type: +/// +/// ```no_run +/// # fn main() -> serde_dhall::Result<()> { +/// use serde_dhall::options; +/// +/// let ty = options::from_str("{ x: Natural, y: Natural }").parse()?; +/// let data = options::from_file("foo.dhall") +/// .type_annotation(&ty) +/// .parse()?; +/// # Ok(()) +/// # } +/// ``` +#[derive(Debug, Clone)] +pub struct Options<'a, T> { + source: Source<'a>, + annot: Option, + allow_imports: bool, + // allow_remote_imports: bool, + // use_cache: bool, + target_type: std::marker::PhantomData, +} + +impl<'a, T> Options<'a, T> { + fn default_with_source(source: Source<'a>) -> Self { + Options { + source, + annot: None, + allow_imports: true, + // allow_remote_imports: true, + // use_cache: true, + target_type: std::marker::PhantomData, + } + } + fn from_str(s: &'a str) -> Self { + Self::default_with_source(Source::Str(s)) + } + fn from_file>(path: P) -> Self { + Self::default_with_source(Source::File(path.as_ref().to_owned())) + } + // fn from_url(url: &'a str) -> Self { + // Self::default_with_source(Source::Url(url)) + // } + + pub fn imports(&mut self, imports: bool) -> &mut Self { + self.allow_imports = imports; + self + } + // pub fn remote_imports(&mut self, imports: bool) -> &mut Self { + // self.allow_remote_imports = imports; + // if imports { + // self.allow_imports = true; + // } + // self + // } + pub fn type_annotation(&mut self, ty: &SimpleType) -> &mut Self { + self.annot = Some(ty.clone()); + self + } + pub fn static_type_annotation(&mut self) -> &mut Self + where + T: StaticType, + { + self.annot = Some(T::static_type()); + self + } + + fn _parse(&self) -> dhall::error::Result { + let parsed = match &self.source { + Source::Str(s) => Parsed::parse_str(s)?, + Source::File(p) => Parsed::parse_file(p.as_ref())?, + }; + let resolved = if self.allow_imports { + parsed.resolve()? + } else { + parsed.skip_resolve()? + }; + let typed = match &self.annot { + None => resolved.typecheck()?, + Some(ty) => resolved.typecheck_with(&ty.to_value().hir)?, + }; + Ok(Value::from_nir(typed.normalize().as_nir())) + } + pub fn parse(&self) -> Result + where + T: Deserialize, + { + let val = self._parse().map_err(Error::Dhall)?; + T::from_dhall(&val) + } +} + +pub fn from_str<'a, T>(s: &'a str) -> Options<'a, T> { + Options::from_str(s) +} +pub fn from_file<'a, T, P: AsRef>(path: P) -> Options<'a, T> { + Options::from_file(path) +} +// pub fn from_url<'a, T>(url: &'a str) -> Options<'a, T> { +// Options::from_url(url) +// } -- cgit v1.2.3 From 002d7c2a74647312a821598ac3d9f5521296873d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 22 Mar 2020 21:25:44 +0000 Subject: Add a bunch of TODOs --- serde_dhall/src/options.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index 542804b..19b8587 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -48,6 +48,7 @@ enum Source<'a> { /// # Ok(()) /// # } /// ``` +/// /// TODO #[derive(Debug, Clone)] pub struct Options<'a, T> { source: Source<'a>, @@ -69,9 +70,11 @@ impl<'a, T> Options<'a, T> { target_type: std::marker::PhantomData, } } + /// TODO fn from_str(s: &'a str) -> Self { Self::default_with_source(Source::Str(s)) } + /// TODO fn from_file>(path: P) -> Self { Self::default_with_source(Source::File(path.as_ref().to_owned())) } @@ -79,6 +82,7 @@ impl<'a, T> Options<'a, T> { // Self::default_with_source(Source::Url(url)) // } + /// TODO pub fn imports(&mut self, imports: bool) -> &mut Self { self.allow_imports = imports; self @@ -90,10 +94,12 @@ impl<'a, T> Options<'a, T> { // } // self // } + // /// TODO pub fn type_annotation(&mut self, ty: &SimpleType) -> &mut Self { self.annot = Some(ty.clone()); self } + /// TODO pub fn static_type_annotation(&mut self) -> &mut Self where T: StaticType, @@ -118,6 +124,7 @@ impl<'a, T> Options<'a, T> { }; Ok(Value::from_nir(typed.normalize().as_nir())) } + /// TODO pub fn parse(&self) -> Result where T: Deserialize, @@ -127,9 +134,11 @@ impl<'a, T> Options<'a, T> { } } +/// TODO pub fn from_str<'a, T>(s: &'a str) -> Options<'a, T> { Options::from_str(s) } +/// TODO pub fn from_file<'a, T, P: AsRef>(path: P) -> Options<'a, T> { Options::from_file(path) } -- cgit v1.2.3 From a70922c6c6beb58a45da80f15576b54fb915ec28 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 22 Mar 2020 22:11:00 +0000 Subject: Rework SimpleType --- serde_dhall/src/options.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index 19b8587..0072393 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; use dhall::Parsed; -use crate::simple::Type as SimpleType; +use crate::SimpleType; use crate::{Deserialize, Error, Result, StaticType, Value}; #[derive(Debug, Clone)] @@ -94,7 +94,8 @@ impl<'a, T> Options<'a, T> { // } // self // } - // /// TODO + // + /// TODO pub fn type_annotation(&mut self, ty: &SimpleType) -> &mut Self { self.annot = Some(ty.clone()); self -- cgit v1.2.3 From 3a5f2044954aae7278f16e30561a81626dba6923 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 22 Mar 2020 22:27:56 +0000 Subject: Move mod simple into value --- serde_dhall/src/options.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index 0072393..f468cf0 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -121,7 +121,7 @@ impl<'a, T> Options<'a, T> { }; let typed = match &self.annot { None => resolved.typecheck()?, - Some(ty) => resolved.typecheck_with(&ty.to_value().hir)?, + Some(ty) => resolved.typecheck_with(ty.to_value().as_hir())?, }; Ok(Value::from_nir(typed.normalize().as_nir())) } -- cgit v1.2.3 From f9848b54fe2e64901042fba66fb471999f415ff1 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 24 Mar 2020 18:53:25 +0000 Subject: Hide serde Error internals --- serde_dhall/src/options.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index f468cf0..f260572 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use dhall::Parsed; use crate::SimpleType; -use crate::{Deserialize, Error, Result, StaticType, Value}; +use crate::{Deserialize, Error, ErrorKind, Result, StaticType, Value}; #[derive(Debug, Clone)] enum Source<'a> { @@ -130,7 +130,7 @@ impl<'a, T> Options<'a, T> { where T: Deserialize, { - let val = self._parse().map_err(Error::Dhall)?; + let val = self._parse().map_err(ErrorKind::Dhall).map_err(Error)?; T::from_dhall(&val) } } -- cgit v1.2.3 From 158117e4096f5af571e79e1a33d91f09e7b2cc5d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 11:39:58 +0100 Subject: Rename Options to Deserializer --- serde_dhall/src/options.rs | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index f260572..237647f 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -12,13 +12,13 @@ enum Source<'a> { // Url(&'a str), } -/// Options and flags which can be used to configure how a dhall value is read. +/// Controls how a dhall value is read. /// /// This builder exposes the ability to configure how a value is deserialized and what operations /// are permitted during evaluation. The functions in the crate root are aliases for /// commonly used options using this builder. /// -/// Generally speaking, when using `Options`, you'll create it with `from_str` or `from_file`, then +/// Generally speaking, when using `Deserializer`, you'll create it with `from_str` or `from_file`, then /// chain calls to methods to set each option, then call `parse`. This will give you a /// `serde_dhall::Result` where `T` a deserializable type of your choice. /// @@ -48,9 +48,9 @@ enum Source<'a> { /// # Ok(()) /// # } /// ``` -/// /// TODO +/// TODO #[derive(Debug, Clone)] -pub struct Options<'a, T> { +pub struct Deserializer<'a, T> { source: Source<'a>, annot: Option, allow_imports: bool, @@ -59,9 +59,9 @@ pub struct Options<'a, T> { target_type: std::marker::PhantomData, } -impl<'a, T> Options<'a, T> { +impl<'a, T> Deserializer<'a, T> { fn default_with_source(source: Source<'a>) -> Self { - Options { + Deserializer { source, annot: None, allow_imports: true, @@ -135,14 +135,22 @@ impl<'a, T> Options<'a, T> { } } -/// TODO -pub fn from_str<'a, T>(s: &'a str) -> Options<'a, T> { - Options::from_str(s) +/// Deserialize an instance of type `T` from a string of Dhall text. +/// +/// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized value, or +/// use other [`Deserializer`] methods to add type annotations or control import behavior beforehand. +/// +/// [`Deserializer`]: struct.Deserializer.html +/// [`parse`]: struct.Deserializer.html#method.parse +pub fn from_str<'a, T>(s: &'a str) -> Deserializer<'a, T> { + Deserializer::from_str(s) } + /// TODO -pub fn from_file<'a, T, P: AsRef>(path: P) -> Options<'a, T> { - Options::from_file(path) +pub fn from_file<'a, T, P: AsRef>(path: P) -> Deserializer<'a, T> { + Deserializer::from_file(path) } -// pub fn from_url<'a, T>(url: &'a str) -> Options<'a, T> { -// Options::from_url(url) + +// pub fn from_url<'a, T>(url: &'a str) -> Deserializer<'a, T> { +// Deserializer::from_url(url) // } -- cgit v1.2.3 From 15a0902b50ff6d1b36dbf7a220b6ff42ceefada6 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 11:43:22 +0100 Subject: Rename Deserialize trait to FromDhall --- serde_dhall/src/options.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index 237647f..d7a91a2 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use dhall::Parsed; use crate::SimpleType; -use crate::{Deserialize, Error, ErrorKind, Result, StaticType, Value}; +use crate::{FromDhall, Error, ErrorKind, Result, StaticType, Value}; #[derive(Debug, Clone)] enum Source<'a> { @@ -128,7 +128,7 @@ impl<'a, T> Deserializer<'a, T> { /// TODO pub fn parse(&self) -> Result where - T: Deserialize, + T: FromDhall, { let val = self._parse().map_err(ErrorKind::Dhall).map_err(Error)?; T::from_dhall(&val) -- cgit v1.2.3 From 6dab8cb06e52efdb18b9dcf975e0a2d50454d704 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 15:42:45 +0100 Subject: Document Deserializer methods --- serde_dhall/src/options.rs | 213 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 197 insertions(+), 16 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index d7a91a2..f3797ee 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use dhall::Parsed; use crate::SimpleType; -use crate::{FromDhall, Error, ErrorKind, Result, StaticType, Value}; +use crate::{Error, ErrorKind, FromDhall, Result, StaticType, Value}; #[derive(Debug, Clone)] enum Source<'a> { @@ -15,12 +15,11 @@ enum Source<'a> { /// Controls how a dhall value is read. /// /// This builder exposes the ability to configure how a value is deserialized and what operations -/// are permitted during evaluation. The functions in the crate root are aliases for -/// commonly used options using this builder. +/// are permitted during evaluation. /// /// Generally speaking, when using `Deserializer`, you'll create it with `from_str` or `from_file`, then /// chain calls to methods to set each option, then call `parse`. This will give you a -/// `serde_dhall::Result` where `T` a deserializable type of your choice. +/// `serde_dhall::Result` where `T` is a deserializable type of your choice. /// /// # Examples /// @@ -48,8 +47,7 @@ enum Source<'a> { /// # Ok(()) /// # } /// ``` -/// TODO -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Deserializer<'a, T> { source: Source<'a>, annot: Option, @@ -70,11 +68,9 @@ impl<'a, T> Deserializer<'a, T> { target_type: std::marker::PhantomData, } } - /// TODO fn from_str(s: &'a str) -> Self { Self::default_with_source(Source::Str(s)) } - /// TODO fn from_file>(path: P) -> Self { Self::default_with_source(Source::File(path.as_ref().to_owned())) } @@ -82,11 +78,36 @@ impl<'a, T> Deserializer<'a, T> { // Self::default_with_source(Source::Url(url)) // } - /// TODO + /// Sets whether to enable imports. + /// + /// By default, imports are enabled. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> serde_dhall::Result<()> { + /// use serde::Deserialize; + /// use serde_dhall::SimpleType; + /// + /// let data = "12 + ./other_file.dhall : Natural"; + /// assert!( + /// serde_dhall::options::from_str::(data) + /// .imports(false) + /// .parse() + /// .is_err() + /// ); + /// # Ok(()) + /// # } + /// ``` + /// + /// [`static_type_annotation`]: struct.Deserializer.html#method.static_type_annotation + /// [`StaticType`]: trait.StaticType.html pub fn imports(&mut self, imports: bool) -> &mut Self { self.allow_imports = imports; self } + + // /// TODO // pub fn remote_imports(&mut self, imports: bool) -> &mut Self { // self.allow_remote_imports = imports; // if imports { @@ -94,13 +115,98 @@ impl<'a, T> Deserializer<'a, T> { // } // self // } - // - /// TODO + + /// Ensures that the parsed value matches the provided type. + /// + /// In many cases the Dhall type that corresponds to a Rust type can be inferred automatically. + /// See the [`StaticType`] trait and the [`static_type_annotation`] method. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> serde_dhall::Result<()> { + /// use serde::Deserialize; + /// use serde_dhall::SimpleType; + /// + /// #[derive(Deserialize)] + /// struct Point { + /// x: u64, + /// y: Option, + /// } + /// + /// // Parse a Dhall type + /// let point_type_str = "{ x: Natural, y: Optional Natural }"; + /// let point_type: SimpleType = serde_dhall::options::from_str(point_type_str).parse()?; + /// + /// // Parse some Dhall data to a Point. + /// let data = "{ x = 1, y = Some (1 + 1) }"; + /// let point: Point = serde_dhall::options::from_str(data) + /// .type_annotation(&point_type) + /// .parse()?; + /// assert_eq!(point.x, 1); + /// assert_eq!(point.y, Some(2)); + /// + /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. + /// let invalid_data = "{ x = 1 }"; + /// assert!( + /// serde_dhall::options::from_str::(invalid_data) + /// .type_annotation(&point_type) + /// .parse() + /// .is_err() + /// ); + /// # Ok(()) + /// # } + /// ``` + /// + /// [`static_type_annotation`]: struct.Deserializer.html#method.static_type_annotation + /// [`StaticType`]: trait.StaticType.html pub fn type_annotation(&mut self, ty: &SimpleType) -> &mut Self { self.annot = Some(ty.clone()); self } - /// TODO + + /// Ensures that the parsed value matches the type of `T`. + /// + /// `T` must implement the [`StaticType`] trait. If it doesn't, you can use [`type_annotation`] + /// to provide a type manually. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> serde_dhall::Result<()> { + /// use serde::Deserialize; + /// use serde_dhall::StaticType; + /// + /// #[derive(Deserialize, StaticType)] + /// struct Point { + /// x: u64, + /// y: Option, + /// } + /// + /// // Some Dhall data + /// let data = "{ x = 1, y = Some (1 + 1) }"; + /// + /// // Convert the Dhall string to a Point. + /// let point: Point = serde_dhall::options::from_str(data) + /// .static_type_annotation() + /// .parse()?; + /// assert_eq!(point.x, 1); + /// assert_eq!(point.y, Some(2)); + /// + /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. + /// let invalid_data = "{ x = 1 }"; + /// assert!( + /// serde_dhall::options::from_str::(invalid_data) + /// .static_type_annotation() + /// .parse() + /// .is_err() + /// ); + /// # Ok(()) + /// # } + /// ``` + /// + /// [`type_annotation`]: struct.Deserializer.html#method.type_annotation + /// [`StaticType`]: trait.StaticType.html pub fn static_type_annotation(&mut self) -> &mut Self where T: StaticType, @@ -125,7 +231,20 @@ impl<'a, T> Deserializer<'a, T> { }; Ok(Value::from_nir(typed.normalize().as_nir())) } - /// TODO + + /// Parses the chosen dhall value with the options provided. + /// + /// # Examples + /// + /// Reading from a file: + /// + /// ```no_run + /// # fn main() -> serde_dhall::Result<()> { + /// use serde_dhall::options; + /// let data = options::from_file("foo.dhall").parse()?; + /// # Ok(()) + /// # } + /// ``` pub fn parse(&self) -> Result where T: FromDhall, @@ -138,15 +257,65 @@ impl<'a, T> Deserializer<'a, T> { /// Deserialize an instance of type `T` from a string of Dhall text. /// /// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized value, or -/// use other [`Deserializer`] methods to add type annotations or control import behavior beforehand. +/// use other [`Deserializer`] methods to e.g. add type annotations beforehand. +/// +/// # Example +/// +/// ```rust +/// # fn main() -> serde_dhall::Result<()> { +/// use serde::Deserialize; +/// +/// // We use serde's derive feature +/// #[derive(Deserialize)] +/// struct Point { +/// x: u64, +/// y: u64, +/// } +/// +/// // Some Dhall data +/// let data = "{ x = 1, y = 1 + 1 } : { x: Natural, y: Natural }"; +/// +/// // Parse the Dhall string as a Point. +/// let point: Point = serde_dhall::options::from_str(data).parse()?; +/// +/// assert_eq!(point.x, 1); +/// assert_eq!(point.y, 2); +/// # Ok(()) +/// # } +/// ``` /// /// [`Deserializer`]: struct.Deserializer.html /// [`parse`]: struct.Deserializer.html#method.parse -pub fn from_str<'a, T>(s: &'a str) -> Deserializer<'a, T> { +pub fn from_str(s: &str) -> Deserializer<'_, T> { Deserializer::from_str(s) } -/// TODO +/// Deserialize an instance of type `T` from a Dhall file. +/// +/// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized value, or +/// use other [`Deserializer`] methods to e.g. add type annotations beforehand. +/// +/// # Example +/// +/// ```no_run +/// # fn main() -> serde_dhall::Result<()> { +/// use serde::Deserialize; +/// +/// // We use serde's derive feature +/// #[derive(Deserialize)] +/// struct Point { +/// x: u64, +/// y: u64, +/// } +/// +/// // Parse the Dhall file as a Point. +/// let point: Point = serde_dhall::options::from_file("foo.dhall").parse()?; +/// # Ok(()) +/// # } +/// ``` +/// +/// [`Deserializer`]: struct.Deserializer.html +/// [`parse`]: struct.Deserializer.html#method.parse pub fn from_file<'a, T, P: AsRef>(path: P) -> Deserializer<'a, T> { Deserializer::from_file(path) } @@ -154,3 +323,15 @@ pub fn from_file<'a, T, P: AsRef>(path: P) -> Deserializer<'a, T> { // pub fn from_url<'a, T>(url: &'a str) -> Deserializer<'a, T> { // Deserializer::from_url(url) // } + +// Custom impl to not get a Clone bound on T +impl<'a, T> Clone for Deserializer<'a, T> { + fn clone(&self) -> Self { + Deserializer { + source: self.source.clone(), + annot: self.annot.clone(), + allow_imports: self.allow_imports.clone(), + target_type: std::marker::PhantomData, + } + } +} -- cgit v1.2.3 From 678d254a06dbb75f5398abaacee41d1712bf7194 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 15:53:15 +0100 Subject: Make Deserializer functions the only functions --- serde_dhall/src/options.rs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index f3797ee..c44de90 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -27,9 +27,9 @@ enum Source<'a> { /// /// ```no_run /// # fn main() -> serde_dhall::Result<()> { -/// use serde_dhall::options; +/// use serde_dhall::from_file; /// -/// let data = options::from_file("foo.dhall").parse()?; +/// let data = from_file("foo.dhall").parse()?; /// # Ok(()) /// # } /// ``` @@ -38,10 +38,10 @@ enum Source<'a> { /// /// ```no_run /// # fn main() -> serde_dhall::Result<()> { -/// use serde_dhall::options; +/// use serde_dhall::{from_file, from_str}; /// -/// let ty = options::from_str("{ x: Natural, y: Natural }").parse()?; -/// let data = options::from_file("foo.dhall") +/// let ty = from_str("{ x: Natural, y: Natural }").parse()?; +/// let data = from_file("foo.dhall") /// .type_annotation(&ty) /// .parse()?; /// # Ok(()) @@ -91,7 +91,7 @@ impl<'a, T> Deserializer<'a, T> { /// /// let data = "12 + ./other_file.dhall : Natural"; /// assert!( - /// serde_dhall::options::from_str::(data) + /// serde_dhall::from_str::(data) /// .imports(false) /// .parse() /// .is_err() @@ -136,11 +136,11 @@ impl<'a, T> Deserializer<'a, T> { /// /// // Parse a Dhall type /// let point_type_str = "{ x: Natural, y: Optional Natural }"; - /// let point_type: SimpleType = serde_dhall::options::from_str(point_type_str).parse()?; + /// let point_type: SimpleType = serde_dhall::from_str(point_type_str).parse()?; /// /// // Parse some Dhall data to a Point. /// let data = "{ x = 1, y = Some (1 + 1) }"; - /// let point: Point = serde_dhall::options::from_str(data) + /// let point: Point = serde_dhall::from_str(data) /// .type_annotation(&point_type) /// .parse()?; /// assert_eq!(point.x, 1); @@ -149,7 +149,7 @@ impl<'a, T> Deserializer<'a, T> { /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. /// let invalid_data = "{ x = 1 }"; /// assert!( - /// serde_dhall::options::from_str::(invalid_data) + /// serde_dhall::from_str::(invalid_data) /// .type_annotation(&point_type) /// .parse() /// .is_err() @@ -187,7 +187,7 @@ impl<'a, T> Deserializer<'a, T> { /// let data = "{ x = 1, y = Some (1 + 1) }"; /// /// // Convert the Dhall string to a Point. - /// let point: Point = serde_dhall::options::from_str(data) + /// let point: Point = serde_dhall::from_str(data) /// .static_type_annotation() /// .parse()?; /// assert_eq!(point.x, 1); @@ -196,7 +196,7 @@ impl<'a, T> Deserializer<'a, T> { /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. /// let invalid_data = "{ x = 1 }"; /// assert!( - /// serde_dhall::options::from_str::(invalid_data) + /// serde_dhall::from_str::(invalid_data) /// .static_type_annotation() /// .parse() /// .is_err() @@ -240,8 +240,7 @@ impl<'a, T> Deserializer<'a, T> { /// /// ```no_run /// # fn main() -> serde_dhall::Result<()> { - /// use serde_dhall::options; - /// let data = options::from_file("foo.dhall").parse()?; + /// let data = serde_dhall::from_file("foo.dhall").parse()?; /// # Ok(()) /// # } /// ``` @@ -276,7 +275,7 @@ impl<'a, T> Deserializer<'a, T> { /// let data = "{ x = 1, y = 1 + 1 } : { x: Natural, y: Natural }"; /// /// // Parse the Dhall string as a Point. -/// let point: Point = serde_dhall::options::from_str(data).parse()?; +/// let point: Point = serde_dhall::from_str(data).parse()?; /// /// assert_eq!(point.x, 1); /// assert_eq!(point.y, 2); @@ -309,7 +308,7 @@ pub fn from_str(s: &str) -> Deserializer<'_, T> { /// } /// /// // Parse the Dhall file as a Point. -/// let point: Point = serde_dhall::options::from_file("foo.dhall").parse()?; +/// let point: Point = serde_dhall::from_file("foo.dhall").parse()?; /// # Ok(()) /// # } /// ``` -- cgit v1.2.3 From 797241ebec5cec686056b5da73864db8eab03d48 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 16:36:54 +0100 Subject: Rewrite builder with state machine to allow parse::<> --- serde_dhall/src/options.rs | 203 ++++++++++++++++++++++++++------------------- 1 file changed, 117 insertions(+), 86 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index c44de90..a20891a 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -12,6 +12,32 @@ enum Source<'a> { // Url(&'a str), } +#[derive(Debug, Clone)] +pub struct NoAnnot; +#[derive(Debug, Clone)] +pub struct ManualAnnot(SimpleType); +#[derive(Debug, Clone)] +pub struct StaticAnnot; + +pub trait HasAnnot { + fn get_annot(a: &A) -> Option; +} +impl HasAnnot for T { + fn get_annot(_: &NoAnnot) -> Option { + None + } +} +impl HasAnnot for T { + fn get_annot(a: &ManualAnnot) -> Option { + Some(a.0.clone()) + } +} +impl HasAnnot for T { + fn get_annot(_: &StaticAnnot) -> Option { + Some(T::static_type()) + } +} + /// Controls how a dhall value is read. /// /// This builder exposes the ability to configure how a value is deserialized and what operations @@ -29,7 +55,7 @@ enum Source<'a> { /// # fn main() -> serde_dhall::Result<()> { /// use serde_dhall::from_file; /// -/// let data = from_file("foo.dhall").parse()?; +/// let data = from_file("foo.dhall").parse::()?; /// # Ok(()) /// # } /// ``` @@ -38,34 +64,33 @@ enum Source<'a> { /// /// ```no_run /// # fn main() -> serde_dhall::Result<()> { +/// use std::collections::HashMap; /// use serde_dhall::{from_file, from_str}; /// /// let ty = from_str("{ x: Natural, y: Natural }").parse()?; /// let data = from_file("foo.dhall") /// .type_annotation(&ty) -/// .parse()?; +/// .parse::>()?; /// # Ok(()) /// # } /// ``` -#[derive(Debug)] -pub struct Deserializer<'a, T> { +#[derive(Debug, Clone)] +pub struct Deserializer<'a, A> { source: Source<'a>, - annot: Option, + annot: A, allow_imports: bool, // allow_remote_imports: bool, // use_cache: bool, - target_type: std::marker::PhantomData, } -impl<'a, T> Deserializer<'a, T> { +impl<'a> Deserializer<'a, NoAnnot> { fn default_with_source(source: Source<'a>) -> Self { Deserializer { source, - annot: None, + annot: NoAnnot, allow_imports: true, // allow_remote_imports: true, // use_cache: true, - target_type: std::marker::PhantomData, } } fn from_str(s: &'a str) -> Self { @@ -77,45 +102,9 @@ impl<'a, T> Deserializer<'a, T> { // fn from_url(url: &'a str) -> Self { // Self::default_with_source(Source::Url(url)) // } +} - /// Sets whether to enable imports. - /// - /// By default, imports are enabled. - /// - /// # Examples - /// - /// ``` - /// # fn main() -> serde_dhall::Result<()> { - /// use serde::Deserialize; - /// use serde_dhall::SimpleType; - /// - /// let data = "12 + ./other_file.dhall : Natural"; - /// assert!( - /// serde_dhall::from_str::(data) - /// .imports(false) - /// .parse() - /// .is_err() - /// ); - /// # Ok(()) - /// # } - /// ``` - /// - /// [`static_type_annotation`]: struct.Deserializer.html#method.static_type_annotation - /// [`StaticType`]: trait.StaticType.html - pub fn imports(&mut self, imports: bool) -> &mut Self { - self.allow_imports = imports; - self - } - - // /// TODO - // pub fn remote_imports(&mut self, imports: bool) -> &mut Self { - // self.allow_remote_imports = imports; - // if imports { - // self.allow_imports = true; - // } - // self - // } - +impl<'a> Deserializer<'a, NoAnnot> { /// Ensures that the parsed value matches the provided type. /// /// In many cases the Dhall type that corresponds to a Rust type can be inferred automatically. @@ -136,22 +125,22 @@ impl<'a, T> Deserializer<'a, T> { /// /// // Parse a Dhall type /// let point_type_str = "{ x: Natural, y: Optional Natural }"; - /// let point_type: SimpleType = serde_dhall::from_str(point_type_str).parse()?; + /// let point_type = serde_dhall::from_str(point_type_str).parse::()?; /// /// // Parse some Dhall data to a Point. /// let data = "{ x = 1, y = Some (1 + 1) }"; - /// let point: Point = serde_dhall::from_str(data) + /// let point = serde_dhall::from_str(data) /// .type_annotation(&point_type) - /// .parse()?; + /// .parse::()?; /// assert_eq!(point.x, 1); /// assert_eq!(point.y, Some(2)); /// /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. /// let invalid_data = "{ x = 1 }"; /// assert!( - /// serde_dhall::from_str::(invalid_data) + /// serde_dhall::from_str(invalid_data) /// .type_annotation(&point_type) - /// .parse() + /// .parse::() /// .is_err() /// ); /// # Ok(()) @@ -160,9 +149,15 @@ impl<'a, T> Deserializer<'a, T> { /// /// [`static_type_annotation`]: struct.Deserializer.html#method.static_type_annotation /// [`StaticType`]: trait.StaticType.html - pub fn type_annotation(&mut self, ty: &SimpleType) -> &mut Self { - self.annot = Some(ty.clone()); - self + pub fn type_annotation( + self, + ty: &SimpleType, + ) -> Deserializer<'a, ManualAnnot> { + Deserializer { + annot: ManualAnnot(ty.clone()), + source: self.source, + allow_imports: self.allow_imports, + } } /// Ensures that the parsed value matches the type of `T`. @@ -187,18 +182,18 @@ impl<'a, T> Deserializer<'a, T> { /// let data = "{ x = 1, y = Some (1 + 1) }"; /// /// // Convert the Dhall string to a Point. - /// let point: Point = serde_dhall::from_str(data) + /// let point = serde_dhall::from_str(data) /// .static_type_annotation() - /// .parse()?; + /// .parse::()?; /// assert_eq!(point.x, 1); /// assert_eq!(point.y, Some(2)); /// /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. /// let invalid_data = "{ x = 1 }"; /// assert!( - /// serde_dhall::from_str::(invalid_data) + /// serde_dhall::from_str(invalid_data) /// .static_type_annotation() - /// .parse() + /// .parse::() /// .is_err() /// ); /// # Ok(()) @@ -207,15 +202,60 @@ impl<'a, T> Deserializer<'a, T> { /// /// [`type_annotation`]: struct.Deserializer.html#method.type_annotation /// [`StaticType`]: trait.StaticType.html - pub fn static_type_annotation(&mut self) -> &mut Self - where - T: StaticType, - { - self.annot = Some(T::static_type()); - self + pub fn static_type_annotation(self) -> Deserializer<'a, StaticAnnot> { + Deserializer { + annot: StaticAnnot, + source: self.source, + allow_imports: self.allow_imports, + } + } +} + +impl<'a, A> Deserializer<'a, A> { + /// Sets whether to enable imports. + /// + /// By default, imports are enabled. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> serde_dhall::Result<()> { + /// use serde::Deserialize; + /// use serde_dhall::SimpleType; + /// + /// let data = "12 + ./other_file.dhall : Natural"; + /// assert!( + /// serde_dhall::from_str(data) + /// .imports(false) + /// .parse::() + /// .is_err() + /// ); + /// # Ok(()) + /// # } + /// ``` + /// + /// [`static_type_annotation`]: struct.Deserializer.html#method.static_type_annotation + /// [`StaticType`]: trait.StaticType.html + pub fn imports(self, imports: bool) -> Self { + Deserializer { + allow_imports: imports, + ..self + } } - fn _parse(&self) -> dhall::error::Result { + // /// TODO + // pub fn remote_imports(&mut self, imports: bool) -> &mut Self { + // self.allow_remote_imports = imports; + // if imports { + // self.allow_imports = true; + // } + // self + // } + + fn _parse(&self) -> dhall::error::Result + where + T: HasAnnot, + { let parsed = match &self.source { Source::Str(s) => Parsed::parse_str(s)?, Source::File(p) => Parsed::parse_file(p.as_ref())?, @@ -225,7 +265,7 @@ impl<'a, T> Deserializer<'a, T> { } else { parsed.skip_resolve()? }; - let typed = match &self.annot { + let typed = match &T::get_annot(&self.annot) { None => resolved.typecheck()?, Some(ty) => resolved.typecheck_with(ty.to_value().as_hir())?, }; @@ -240,15 +280,18 @@ impl<'a, T> Deserializer<'a, T> { /// /// ```no_run /// # fn main() -> serde_dhall::Result<()> { - /// let data = serde_dhall::from_file("foo.dhall").parse()?; + /// let data = serde_dhall::from_file("foo.dhall").parse::()?; /// # Ok(()) /// # } /// ``` - pub fn parse(&self) -> Result + pub fn parse(&self) -> Result where - T: FromDhall, + T: FromDhall + HasAnnot, { - let val = self._parse().map_err(ErrorKind::Dhall).map_err(Error)?; + let val = self + ._parse::() + .map_err(ErrorKind::Dhall) + .map_err(Error)?; T::from_dhall(&val) } } @@ -285,7 +328,7 @@ impl<'a, T> Deserializer<'a, T> { /// /// [`Deserializer`]: struct.Deserializer.html /// [`parse`]: struct.Deserializer.html#method.parse -pub fn from_str(s: &str) -> Deserializer<'_, T> { +pub fn from_str(s: &str) -> Deserializer<'_, NoAnnot> { Deserializer::from_str(s) } @@ -315,22 +358,10 @@ pub fn from_str(s: &str) -> Deserializer<'_, T> { /// /// [`Deserializer`]: struct.Deserializer.html /// [`parse`]: struct.Deserializer.html#method.parse -pub fn from_file<'a, T, P: AsRef>(path: P) -> Deserializer<'a, T> { +pub fn from_file<'a, P: AsRef>(path: P) -> Deserializer<'a, NoAnnot> { Deserializer::from_file(path) } -// pub fn from_url<'a, T>(url: &'a str) -> Deserializer<'a, T> { +// pub fn from_url(url: &str) -> Deserializer<'_, NoAnnot> { // Deserializer::from_url(url) // } - -// Custom impl to not get a Clone bound on T -impl<'a, T> Clone for Deserializer<'a, T> { - fn clone(&self) -> Self { - Deserializer { - source: self.source.clone(), - annot: self.annot.clone(), - allow_imports: self.allow_imports.clone(), - target_type: std::marker::PhantomData, - } - } -} -- cgit v1.2.3 From 118c02d330865fcbfb1f2b0028f9404d61b662d8 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 16:42:04 +0100 Subject: Borrow type annotation --- serde_dhall/src/options.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index a20891a..0f18091 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -15,7 +15,7 @@ enum Source<'a> { #[derive(Debug, Clone)] pub struct NoAnnot; #[derive(Debug, Clone)] -pub struct ManualAnnot(SimpleType); +pub struct ManualAnnot<'ty>(&'ty SimpleType); #[derive(Debug, Clone)] pub struct StaticAnnot; @@ -27,8 +27,8 @@ impl HasAnnot for T { None } } -impl HasAnnot for T { - fn get_annot(a: &ManualAnnot) -> Option { +impl<'ty, T> HasAnnot> for T { + fn get_annot(a: &ManualAnnot<'ty>) -> Option { Some(a.0.clone()) } } @@ -38,7 +38,7 @@ impl HasAnnot for T { } } -/// Controls how a dhall value is read. +/// Controls how a Dhall value is read. /// /// This builder exposes the ability to configure how a value is deserialized and what operations /// are permitted during evaluation. @@ -102,9 +102,7 @@ impl<'a> Deserializer<'a, NoAnnot> { // fn from_url(url: &'a str) -> Self { // Self::default_with_source(Source::Url(url)) // } -} -impl<'a> Deserializer<'a, NoAnnot> { /// Ensures that the parsed value matches the provided type. /// /// In many cases the Dhall type that corresponds to a Rust type can be inferred automatically. @@ -149,12 +147,12 @@ impl<'a> Deserializer<'a, NoAnnot> { /// /// [`static_type_annotation`]: struct.Deserializer.html#method.static_type_annotation /// [`StaticType`]: trait.StaticType.html - pub fn type_annotation( + pub fn type_annotation<'ty>( self, - ty: &SimpleType, - ) -> Deserializer<'a, ManualAnnot> { + ty: &'ty SimpleType, + ) -> Deserializer<'a, ManualAnnot<'ty>> { Deserializer { - annot: ManualAnnot(ty.clone()), + annot: ManualAnnot(ty), source: self.source, allow_imports: self.allow_imports, } -- cgit v1.2.3 From 75c0f328c7b6d404353fd078ae12417766ef8a32 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 16:49:15 +0100 Subject: Tweaks --- serde_dhall/src/options.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index 0f18091..ca1e58c 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -12,11 +12,11 @@ enum Source<'a> { // Url(&'a str), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct NoAnnot; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct ManualAnnot<'ty>(&'ty SimpleType); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct StaticAnnot; pub trait HasAnnot { @@ -108,7 +108,7 @@ impl<'a> Deserializer<'a, NoAnnot> { /// In many cases the Dhall type that corresponds to a Rust type can be inferred automatically. /// See the [`StaticType`] trait and the [`static_type_annotation`] method. /// - /// # Examples + /// # Example /// /// ``` /// # fn main() -> serde_dhall::Result<()> { @@ -163,7 +163,7 @@ impl<'a> Deserializer<'a, NoAnnot> { /// `T` must implement the [`StaticType`] trait. If it doesn't, you can use [`type_annotation`] /// to provide a type manually. /// - /// # Examples + /// # Example /// /// ``` /// # fn main() -> serde_dhall::Result<()> { @@ -214,7 +214,7 @@ impl<'a, A> Deserializer<'a, A> { /// /// By default, imports are enabled. /// - /// # Examples + /// # Example /// /// ``` /// # fn main() -> serde_dhall::Result<()> { @@ -272,16 +272,19 @@ impl<'a, A> Deserializer<'a, A> { /// Parses the chosen dhall value with the options provided. /// - /// # Examples + /// If you enabled static annotations, `T` is additional required to implement [`StaticType`]. /// - /// Reading from a file: /// - /// ```no_run + /// # Example + /// + /// ``` /// # fn main() -> serde_dhall::Result<()> { - /// let data = serde_dhall::from_file("foo.dhall").parse::()?; + /// let data = serde_dhall::from_str("6 * 7").parse::()?; + /// assert_eq!(data, 42) /// # Ok(()) /// # } /// ``` + /// [`StaticType`]: trait.StaticType.html pub fn parse(&self) -> Result where T: FromDhall + HasAnnot, -- cgit v1.2.3 From c4d9e73126131d31e707822b0fd8b0710363c863 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 5 Apr 2020 17:12:08 +0100 Subject: Final doc tweaks --- serde_dhall/src/options.rs | 64 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'serde_dhall/src/options.rs') diff --git a/serde_dhall/src/options.rs b/serde_dhall/src/options.rs index ca1e58c..06a4368 100644 --- a/serde_dhall/src/options.rs +++ b/serde_dhall/src/options.rs @@ -43,9 +43,15 @@ impl HasAnnot for T { /// This builder exposes the ability to configure how a value is deserialized and what operations /// are permitted during evaluation. /// -/// Generally speaking, when using `Deserializer`, you'll create it with `from_str` or `from_file`, then -/// chain calls to methods to set each option, then call `parse`. This will give you a -/// `serde_dhall::Result` where `T` is a deserializable type of your choice. +/// Generally speaking, when using [`Deserializer`], you'll create it with [`from_str`] or [`from_file`], then +/// chain calls to methods to set each option, then call [`parse`]. This will give you a +/// [`Result`] where `T` is a deserializable type of your choice. +/// +/// [`Deserializer`]: struct.Deserializer.html +/// [`from_str`]: fn.from_str.html +/// [`from_file`]: fn.from_file.html +/// [`parse`]: struct.Deserializer.html#method.parse +/// [`Result`]: type.Result.html /// /// # Examples /// @@ -106,39 +112,33 @@ impl<'a> Deserializer<'a, NoAnnot> { /// Ensures that the parsed value matches the provided type. /// /// In many cases the Dhall type that corresponds to a Rust type can be inferred automatically. - /// See the [`StaticType`] trait and the [`static_type_annotation`] method. + /// See the [`StaticType`] trait and the [`static_type_annotation`] method for that. /// /// # Example /// /// ``` /// # fn main() -> serde_dhall::Result<()> { + /// use std::collections::HashMap; /// use serde::Deserialize; - /// use serde_dhall::SimpleType; - /// - /// #[derive(Deserialize)] - /// struct Point { - /// x: u64, - /// y: Option, - /// } + /// use serde_dhall::{from_str, SimpleType}; /// /// // Parse a Dhall type - /// let point_type_str = "{ x: Natural, y: Optional Natural }"; - /// let point_type = serde_dhall::from_str(point_type_str).parse::()?; + /// let type_str = "{ x: Natural, y: Natural }"; + /// let ty = from_str(type_str).parse::()?; /// - /// // Parse some Dhall data to a Point. - /// let data = "{ x = 1, y = Some (1 + 1) }"; - /// let point = serde_dhall::from_str(data) - /// .type_annotation(&point_type) - /// .parse::()?; - /// assert_eq!(point.x, 1); - /// assert_eq!(point.y, Some(2)); + /// // Parse some Dhall data. + /// let data = "{ x = 1, y = 1 + 1 }"; + /// let point = from_str(data) + /// .type_annotation(&ty) + /// .parse::>()?; + /// assert_eq!(point.get("y"), Some(&2)); /// /// // Invalid data fails the type validation; deserialization would have succeeded otherwise. - /// let invalid_data = "{ x = 1 }"; + /// let invalid_data = "{ x = 1, z = 3 }"; /// assert!( - /// serde_dhall::from_str(invalid_data) - /// .type_annotation(&point_type) - /// .parse::() + /// from_str(invalid_data) + /// .type_annotation(&ty) + /// .parse::>() /// .is_err() /// ); /// # Ok(()) @@ -272,7 +272,7 @@ impl<'a, A> Deserializer<'a, A> { /// Parses the chosen dhall value with the options provided. /// - /// If you enabled static annotations, `T` is additional required to implement [`StaticType`]. + /// If you enabled static annotations, `T` is required to implement [`StaticType`]. /// /// /// # Example @@ -280,7 +280,7 @@ impl<'a, A> Deserializer<'a, A> { /// ``` /// # fn main() -> serde_dhall::Result<()> { /// let data = serde_dhall::from_str("6 * 7").parse::()?; - /// assert_eq!(data, 42) + /// assert_eq!(data, 42); /// # Ok(()) /// # } /// ``` @@ -297,10 +297,10 @@ impl<'a, A> Deserializer<'a, A> { } } -/// Deserialize an instance of type `T` from a string of Dhall text. +/// Deserialize a value from a string of Dhall text. /// -/// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized value, or -/// use other [`Deserializer`] methods to e.g. add type annotations beforehand. +/// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized +/// value, or use other [`Deserializer`] methods to control the deserialization process. /// /// # Example /// @@ -333,10 +333,10 @@ pub fn from_str(s: &str) -> Deserializer<'_, NoAnnot> { Deserializer::from_str(s) } -/// Deserialize an instance of type `T` from a Dhall file. +/// Deserialize a value from a Dhall file. /// -/// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized value, or -/// use other [`Deserializer`] methods to e.g. add type annotations beforehand. +/// This returns a [`Deserializer`] object. Call the [`parse`] method to get the deserialized +/// value, or use other [`Deserializer`] methods to control the deserialization process. /// /// # Example /// -- cgit v1.2.3