From 4366f6d61fa87e7aa7d327932b593b5da31bcf36 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 9 Feb 2017 10:21:35 -0800 Subject: [PATCH] Expose EDN as_ methods that return copied values, not references. --- edn/src/types.rs | 39 +++++++++++++++++++++++++++------------ edn/tests/tests.rs | 17 ++++++++++++++--- 2 files changed, 41 insertions(+), 15 deletions(-) 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,