Skip to content

Commit

Permalink
New trait impls
Browse files Browse the repository at this point in the history
Improved HashMap trait impl
  • Loading branch information
TedDriggs committed May 26, 2017
1 parent a14ac7c commit ebcc1b3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
27 changes: 24 additions & 3 deletions core/src/from_meta_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use {Error, Result};
/// * As a raw string literal, e.g. `foo = r#"hello "world""#`.
///
/// ## ()
/// * Word with no value specified, e.g. `foo`. This is best used with `Option`.
/// * Word with no value specified, e.g. `foo`. This is best used with `Option`.
/// See `darling::util::Flag` for a more strongly-typed alternative.
///
/// ## Option
/// * Any format produces `Some`.
Expand Down Expand Up @@ -189,6 +190,14 @@ impl<T: FromMetaItem> FromMetaItem for Result<T> {
}
}

/// Parses the meta-item, and in case of error preserves a copy of the input for
/// later analysis.
impl<T: FromMetaItem> FromMetaItem for ::std::result::Result<T, MetaItem> {
fn from_meta_item(item: &MetaItem) -> Result<Self> {
T::from_meta_item(item).map(Ok).or_else(|_| Ok(Err(item.clone())))
}
}

impl<T: FromMetaItem> FromMetaItem for Rc<T> {
fn from_meta_item(item: &MetaItem) -> Result<Self> {
Ok(Rc::new(FromMetaItem::from_meta_item(item)?))
Expand All @@ -214,7 +223,11 @@ impl<V: FromMetaItem> FromMetaItem for HashMap<String, V> {
if let syn::NestedMetaItem::MetaItem(ref inner) = *item {
match map.entry(inner.name().to_string()) {
Entry::Occupied(_) => return Err(Error::duplicate_field(inner.name())),
Entry::Vacant(entry) => { entry.insert(FromMetaItem::from_meta_item(inner)?); }
Entry::Vacant(entry) => {
entry.insert(
FromMetaItem::from_meta_item(inner).map_err(|e| e.at(inner.name()))?
);
}
}
}
}
Expand All @@ -229,7 +242,7 @@ impl<V: FromMetaItem> FromMetaItem for HashMap<String, V> {
mod tests {
use syn;

use {FromMetaItem};
use {FromMetaItem, Result};

/// parse a string as a syn::MetaItem instance.
fn pmi(s: &str) -> ::std::result::Result<syn::MetaItem, String> {
Expand Down Expand Up @@ -290,4 +303,12 @@ mod tests {

assert_eq!(fmi::<HashMap<String, bool>>(r#"ignore(hello, world = false, there = "true")"#), comparison);
}

/// Tests that fallible parsing will always produce an outer `Ok` (from `fmi`),
/// and will accurately preserve the inner contents.
#[test]
fn darling_result_succeeds() {
fmi::<Result<()>>("ignore").unwrap();
fmi::<Result<()>>("ignore(world)").unwrap_err();
}
}
14 changes: 13 additions & 1 deletion core/src/from_variant.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use syn::Variant;
use syn::{self, Variant};

use Result;

Expand All @@ -18,4 +18,16 @@ impl FromVariant for Variant {
fn from_variant(variant: &Variant) -> Result<Self> {
Ok(variant.clone())
}
}

impl FromVariant for syn::Ident {
fn from_variant(variant: &Variant) -> Result<Self> {
Ok(variant.ident.clone())
}
}

impl FromVariant for Vec<syn::Attribute> {
fn from_variant(variant: &Variant) -> Result<Self> {
Ok(variant.attrs.clone())
}
}
8 changes: 8 additions & 0 deletions core/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Utility types for attribute parsing.

use std::ops::{Deref, Not, BitAnd, BitOr};

use syn;
Expand All @@ -17,6 +18,7 @@ pub use self::over_ride::Override;
pub struct Flag(Option<()>);

impl Flag {
/// Creates a new `Flag` which corresponds to the presence of a value.
pub fn present() -> Self {
Flag(Some(()))
}
Expand Down Expand Up @@ -47,6 +49,12 @@ impl From<bool> for Flag {
}
}

impl From<Option<()>> for Flag {
fn from(v: Option<()>) -> Self {
Flag::from(v.is_some())
}
}

impl PartialEq<Option<()>> for Flag {
fn eq(&self, rhs: &Option<()>) -> bool {
self.0 == *rhs
Expand Down

0 comments on commit ebcc1b3

Please sign in to comment.