diff --git a/edn/src/types.rs b/edn/src/types.rs
index cdfaeb2f..6f5f0c60 100644
--- a/edn/src/types.rs
+++ b/edn/src/types.rs
@@ -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 ``.
+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()`,
/// which returns the underlying value representing this Value wrapped
/// in an Option, like ` `.
-macro_rules! def_as {
+macro_rules! def_as_ref {
($name: ident, $kind: path, $t: ty) => {
pub fn $name(&self) -> Option<&$t> {
match *self { $kind(ref v) => Some(v), _ => None }
@@ -148,19 +159,23 @@ impl Value {
match *self { Nil => Some(()), _ => None }
}
+ pub fn as_float(&self) -> Option {
+ self.as_ordered_float().map(|x| (*x).into())
+ }
+
def_as!(as_boolean, Boolean, bool);
def_as!(as_integer, Integer, i64);
- def_as!(as_big_integer, BigInteger, BigInt);
- def_as!(as_float, Float, OrderedFloat);
- def_as!(as_text, Text, String);
- def_as!(as_symbol, PlainSymbol, symbols::PlainSymbol);
- def_as!(as_namespaced_symbol, NamespacedSymbol, symbols::NamespacedSymbol);
- def_as!(as_keyword, Keyword, symbols::Keyword);
- def_as!(as_namespaced_keyword, NamespacedKeyword, symbols::NamespacedKeyword);
- def_as!(as_vector, Vector, Vec);
- def_as!(as_list, List, LinkedList);
- def_as!(as_set, Set, BTreeSet);
- def_as!(as_map, Map, BTreeMap);
+ def_as_ref!(as_big_integer, BigInteger, BigInt);
+ def_as_ref!(as_ordered_float, Float, OrderedFloat);
+ def_as_ref!(as_text, Text, String);
+ def_as_ref!(as_symbol, PlainSymbol, symbols::PlainSymbol);
+ def_as_ref!(as_namespaced_symbol, NamespacedSymbol, symbols::NamespacedSymbol);
+ def_as_ref!(as_keyword, Keyword, symbols::Keyword);
+ def_as_ref!(as_namespaced_keyword, NamespacedKeyword, symbols::NamespacedKeyword);
+ def_as_ref!(as_vector, Vector, Vec);
+ def_as_ref!(as_list, List, LinkedList);
+ def_as_ref!(as_set, Set, BTreeSet);
+ def_as_ref!(as_map, Map, BTreeMap);
pub fn from_bigint(src: &str) -> Option {
src.parse::().map(Value::BigInteger).ok()
diff --git a/edn/tests/tests.rs b/edn/tests/tests.rs
index 9567ea3f..74dbde63 100644
--- a/edn/tests/tests.rs
+++ b/edn/tests/tests.rs
@@ -1003,6 +1003,14 @@ fn test_utils_merge() {
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 {
($value: ident, $method: ident, $is_some: expr, $expected: expr) => {
if $is_some {
@@ -1066,10 +1074,13 @@ fn test_is_and_as_type_helper_functions() {
assert!(!value.as_nil().is_some())
}
- def_test_as_type!(value, as_boolean, i == 1, false);
- def_test_as_type!(value, as_integer, i == 2, 1i64);
+ // These return copied values, not references.
+ 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_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_symbol, i == 6, symbols::PlainSymbol::new("$symbol"));
def_test_as_type!(value, as_namespaced_symbol, i == 7,