Expose EDN as_ methods that return copied values, not references.

This commit is contained in:
Richard Newman 2017-02-09 10:21:35 -08:00
parent 42580539b8
commit 4366f6d61f
2 changed files with 41 additions and 15 deletions

View file

@ -115,10 +115,21 @@ macro_rules! def_is {
} }
} }
/// Creates `as_$TYPE` helper functions for Value, like `as_integer()`,
/// 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) => {
pub fn $name(&self) -> Option<$t> {
match *self { $kind(v) => Some(v), _ => None }
}
}
}
/// Creates `as_$TYPE` helper functions for Value, like `as_big_integer()`, /// Creates `as_$TYPE` helper functions for Value, like `as_big_integer()`,
/// which returns the underlying value representing this Value wrapped /// which returns the underlying value representing this Value wrapped
/// in an Option, like `<Option<&BigInt>`. /// in an Option, like `<Option<&BigInt>`.
macro_rules! def_as { macro_rules! def_as_ref {
($name: ident, $kind: path, $t: ty) => { ($name: ident, $kind: path, $t: ty) => {
pub fn $name(&self) -> Option<&$t> { pub fn $name(&self) -> Option<&$t> {
match *self { $kind(ref v) => Some(v), _ => None } match *self { $kind(ref v) => Some(v), _ => None }
@ -148,19 +159,23 @@ impl Value {
match *self { Nil => Some(()), _ => None } 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_boolean, Boolean, bool);
def_as!(as_integer, Integer, i64); def_as!(as_integer, Integer, i64);
def_as!(as_big_integer, BigInteger, BigInt); def_as_ref!(as_big_integer, BigInteger, BigInt);
def_as!(as_float, Float, OrderedFloat<f64>); def_as_ref!(as_ordered_float, Float, OrderedFloat<f64>);
def_as!(as_text, Text, String); def_as_ref!(as_text, Text, String);
def_as!(as_symbol, PlainSymbol, symbols::PlainSymbol); def_as_ref!(as_symbol, PlainSymbol, symbols::PlainSymbol);
def_as!(as_namespaced_symbol, NamespacedSymbol, symbols::NamespacedSymbol); def_as_ref!(as_namespaced_symbol, NamespacedSymbol, symbols::NamespacedSymbol);
def_as!(as_keyword, Keyword, symbols::Keyword); def_as_ref!(as_keyword, Keyword, symbols::Keyword);
def_as!(as_namespaced_keyword, NamespacedKeyword, symbols::NamespacedKeyword); def_as_ref!(as_namespaced_keyword, NamespacedKeyword, symbols::NamespacedKeyword);
def_as!(as_vector, Vector, Vec<Value>); def_as_ref!(as_vector, Vector, Vec<Value>);
def_as!(as_list, List, LinkedList<Value>); def_as_ref!(as_list, List, LinkedList<Value>);
def_as!(as_set, Set, BTreeSet<Value>); def_as_ref!(as_set, Set, BTreeSet<Value>);
def_as!(as_map, Map, BTreeMap<Value, Value>); def_as_ref!(as_map, Map, BTreeMap<Value, Value>);
pub fn from_bigint(src: &str) -> Option<Value> { pub fn from_bigint(src: &str) -> Option<Value> {
src.parse::<BigInt>().map(Value::BigInteger).ok() src.parse::<BigInt>().map(Value::BigInteger).ok()

View file

@ -1003,6 +1003,14 @@ fn test_utils_merge() {
test(&right, &left, &expected); test(&right, &left, &expected);
} }
macro_rules! def_test_as_value_type {
($value: ident, $method: ident, $is_some: expr, $expected: expr) => {
if $is_some {
assert_eq!($value.$method().unwrap(), $expected)
}
assert_eq!($value.$method().is_some(), $is_some);
}
}
macro_rules! def_test_as_type { macro_rules! def_test_as_type {
($value: ident, $method: ident, $is_some: expr, $expected: expr) => { ($value: ident, $method: ident, $is_some: expr, $expected: expr) => {
if $is_some { if $is_some {
@ -1066,10 +1074,13 @@ fn test_is_and_as_type_helper_functions() {
assert!(!value.as_nil().is_some()) assert!(!value.as_nil().is_some())
} }
def_test_as_type!(value, as_boolean, i == 1, false); // These return copied values, not references.
def_test_as_type!(value, as_integer, i == 2, 1i64); def_test_as_value_type!(value, as_boolean, i == 1, false);
def_test_as_value_type!(value, as_integer, i == 2, 1i64);
def_test_as_value_type!(value, as_float, i == 4, 22.22f64);
def_test_as_type!(value, as_big_integer, i == 3, &max_i64 * &max_i64); def_test_as_type!(value, as_big_integer, i == 3, &max_i64 * &max_i64);
def_test_as_type!(value, as_float, i == 4, OrderedFloat(22.22f64)); 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_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_symbol, i == 6, symbols::PlainSymbol::new("$symbol"));
def_test_as_type!(value, as_namespaced_symbol, i == 7, def_test_as_type!(value, as_namespaced_symbol, i == 7,