Expose EDN into_ methods that consume the edn value, r=jwalker. Fixes 256

Signed-off-by: Victor Porof <victor.porof@gmail.com>
This commit is contained in:
Victor Porof 2017-02-09 20:00:17 +01:00
parent cb40a0f581
commit 49f91b05b0
2 changed files with 62 additions and 13 deletions

View file

@ -119,16 +119,16 @@ macro_rules! def_is {
/// which returns the underlying value representing this Value wrapped
/// in an Option, like `<Option<i64>`.
macro_rules! def_as {
($name: ident, $kind: path, $t: ty) => {
($name: ident, $kind: path, $t: ty, $( $transform: expr ),* ) => {
pub fn $name(&self) -> Option<$t> {
match *self { $kind(v) => Some(v), _ => None }
match *self { $kind(v) => { $( let v = $transform(v) )*; Some(v) }, _ => None }
}
}
}
/// Creates `as_$TYPE` helper functions for Value, like `as_big_integer()`,
/// which returns the underlying value representing this Value wrapped
/// in an Option, like `<Option<&BigInt>`.
/// which returns a reference to the underlying value representing this Value
/// wrapped in an Option, like `<Option<&BigInt>`.
macro_rules! def_as_ref {
($name: ident, $kind: path, $t: ty) => {
pub fn $name(&self) -> Option<&$t> {
@ -137,6 +137,17 @@ macro_rules! def_as_ref {
}
}
/// Creates `into_$TYPE` helper functions for Value, like `into_big_integer()`,
/// which consumes it, returning underlying value representing this Value
/// wrapped in an Option, like `<Option<BigInt>`.
macro_rules! def_into {
($name: ident, $kind: path, $t: ty, $( $transform: expr ),* ) => {
pub fn $name(self) -> Option<$t> {
match self { $kind(v) => { $( let v = $transform(v) )*; Some(v) }, _ => None }
}
}
}
impl Value {
def_is!(is_nil, Nil);
def_is!(is_boolean, Boolean(_));
@ -159,12 +170,10 @@ impl Value {
match *self { Nil => Some(()), _ => None }
}
pub fn as_float(&self) -> Option<f64> {
self.as_ordered_float().map(|x| (*x).into())
}
def_as!(as_boolean, Boolean, bool,);
def_as!(as_integer, Integer, i64,);
def_as!(as_float, Float, f64, |v: OrderedFloat<f64>| v.into_inner());
def_as!(as_boolean, Boolean, bool);
def_as!(as_integer, Integer, i64);
def_as_ref!(as_big_integer, BigInteger, BigInt);
def_as_ref!(as_ordered_float, Float, OrderedFloat<f64>);
def_as_ref!(as_text, Text, String);
@ -177,6 +186,21 @@ impl Value {
def_as_ref!(as_set, Set, BTreeSet<Value>);
def_as_ref!(as_map, Map, BTreeMap<Value, Value>);
def_into!(into_boolean, Boolean, bool,);
def_into!(into_integer, Integer, i64,);
def_into!(into_big_integer, BigInteger, BigInt,);
def_into!(into_ordered_float, Float, OrderedFloat<f64>,);
def_into!(into_float, Float, f64, |v: OrderedFloat<f64>| v.into_inner());
def_into!(into_text, Text, String,);
def_into!(into_symbol, PlainSymbol, symbols::PlainSymbol,);
def_into!(into_namespaced_symbol, NamespacedSymbol, symbols::NamespacedSymbol,);
def_into!(into_keyword, Keyword, symbols::Keyword,);
def_into!(into_namespaced_keyword, NamespacedKeyword, symbols::NamespacedKeyword,);
def_into!(into_vector, Vector, Vec<Value>,);
def_into!(into_list, List, LinkedList<Value>,);
def_into!(into_set, Set, BTreeSet<Value>,);
def_into!(into_map, Map, BTreeMap<Value, Value>,);
pub fn from_bigint(src: &str) -> Option<Value> {
src.parse::<BigInt>().map(Value::BigInteger).ok()
}

View file

@ -1020,6 +1020,15 @@ macro_rules! def_test_as_type {
}
}
macro_rules! def_test_into_type {
($value: ident, $method: ident, $is_some: expr, $expected: expr) => {
if $is_some {
assert_eq!($value.clone().$method().unwrap(), $expected)
}
assert_eq!($value.clone().$method().is_some(), $is_some);
}
}
#[test]
fn test_is_and_as_type_helper_functions() {
let max_i64 = i64::max_value().to_bigint().unwrap();
@ -1083,17 +1092,33 @@ fn test_is_and_as_type_helper_functions() {
def_test_as_type!(value, as_ordered_float, i == 4, OrderedFloat(22.22f64));
def_test_as_type!(value, as_text, i == 5, "hello world".to_string());
def_test_as_type!(value, as_symbol, i == 6, symbols::PlainSymbol::new("$symbol"));
def_test_as_type!(value, as_namespaced_symbol, i == 7,
symbols::NamespacedSymbol::new("$ns", "$symbol"));
def_test_as_type!(value, as_namespaced_symbol, i == 7, symbols::NamespacedSymbol::new("$ns", "$symbol"));
def_test_as_type!(value, as_keyword, i == 8, symbols::Keyword::new("hello"));
def_test_as_type!(value, as_namespaced_keyword, i == 9,
symbols::NamespacedKeyword::new("hello", "world"));
def_test_as_type!(value, as_namespaced_keyword, i == 9, symbols::NamespacedKeyword::new("hello", "world"));
def_test_as_type!(value, as_vector, i == 10, vec![Integer(1)]);
def_test_as_type!(value, as_list, i == 11, LinkedList::from_iter(vec![]));
def_test_as_type!(value, as_set, i == 12, BTreeSet::from_iter(vec![]));
def_test_as_type!(value, as_map, i == 13, BTreeMap::from_iter(vec![
(Value::Text("a".to_string()), Value::Integer(1)),
]));
def_test_into_type!(value, into_boolean, i == 1, false);
def_test_into_type!(value, into_integer, i == 2, 1i64);
def_test_into_type!(value, into_float, i == 4, 22.22f64);
def_test_into_type!(value, into_big_integer, i == 3, &max_i64 * &max_i64);
def_test_into_type!(value, into_ordered_float, i == 4, OrderedFloat(22.22f64));
def_test_into_type!(value, into_text, i == 5, "hello world".to_string());
def_test_into_type!(value, into_symbol, i == 6, symbols::PlainSymbol::new("$symbol"));
def_test_into_type!(value, into_namespaced_symbol, i == 7, symbols::NamespacedSymbol::new("$ns", "$symbol"));
def_test_into_type!(value, into_keyword, i == 8, symbols::Keyword::new("hello"));
def_test_into_type!(value, into_namespaced_keyword, i == 9, symbols::NamespacedKeyword::new("hello", "world"));
def_test_into_type!(value, into_vector, i == 10, vec![Integer(1)]);
def_test_into_type!(value, into_list, i == 11, LinkedList::from_iter(vec![]));
def_test_into_type!(value, into_set, i == 12, BTreeSet::from_iter(vec![]));
def_test_into_type!(value, into_map, i == 13, BTreeMap::from_iter(vec![
(Value::Text("a".to_string()), Value::Integer(1)),
]));
}
}