Add is_$type and as_$type methods to edn::Value types and add tests. Fixes #197
This commit is contained in:
parent
c6fa14c0c8
commit
d116fd7bff
2 changed files with 140 additions and 5 deletions
|
@ -87,13 +87,62 @@ fn test_print_edn() {
|
||||||
Value::Boolean(true))).to_string());
|
Value::Boolean(true))).to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates `is_$TYPE` helper functions for Value, like
|
||||||
|
/// `is_big_integer()` or `is_text()`.
|
||||||
|
macro_rules! def_is {
|
||||||
|
($name: ident, $pat: pat) => {
|
||||||
|
pub fn $name(&self) -> bool {
|
||||||
|
match *self { $pat => true, _ => false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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>`.
|
||||||
|
macro_rules! def_as {
|
||||||
|
($name: ident, $kind: path, $t: ty) => {
|
||||||
|
pub fn $name(&self) -> Option<&$t> {
|
||||||
|
match *self { $kind(ref v) => Some(v), _ => None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn is_keyword(&self) -> bool {
|
def_is!(is_nil, Nil);
|
||||||
match *self {
|
def_is!(is_boolean, Boolean(_));
|
||||||
Keyword(_) => true,
|
def_is!(is_integer, Integer(_));
|
||||||
_ => false,
|
def_is!(is_big_integer, BigInteger(_));
|
||||||
}
|
def_is!(is_float, Float(_));
|
||||||
|
def_is!(is_text, Text(_));
|
||||||
|
def_is!(is_symbol, PlainSymbol(_));
|
||||||
|
def_is!(is_namespaced_symbol, NamespacedSymbol(_));
|
||||||
|
def_is!(is_keyword, Keyword(_));
|
||||||
|
def_is!(is_namespaced_keyword, NamespacedKeyword(_));
|
||||||
|
def_is!(is_vector, Vector(_));
|
||||||
|
def_is!(is_list, List(_));
|
||||||
|
def_is!(is_set, Set(_));
|
||||||
|
def_is!(is_map, Map(_));
|
||||||
|
|
||||||
|
/// `as_nil` does not use the macro as it does not have an underlying
|
||||||
|
/// value, and returns `Option<()>`.
|
||||||
|
pub fn as_nil(&self) -> Option<()> {
|
||||||
|
match *self { Nil => Some(()), _ => None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<f64>);
|
||||||
|
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<Value>);
|
||||||
|
def_as!(as_list, List, LinkedList<Value>);
|
||||||
|
def_as!(as_set, Set, BTreeSet<Value>);
|
||||||
|
def_as!(as_map, Map, BTreeMap<Value, Value>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for Value {
|
impl PartialOrd for Value {
|
||||||
|
|
|
@ -33,6 +33,12 @@ fn k_plain(name: &str) -> Value {
|
||||||
return Keyword(symbols::Keyword::new(name));
|
return Keyword(symbols::Keyword::new(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper for making wrapped symbols with a namespace
|
||||||
|
fn s_ns(ns: &str, name: &str) -> Value {
|
||||||
|
return NamespacedSymbol(symbols::NamespacedSymbol::new(ns, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for making wrapped symbols without a namespace
|
||||||
fn s_plain(name: &str) -> Value {
|
fn s_plain(name: &str) -> Value {
|
||||||
return PlainSymbol(symbols::PlainSymbol::new(name));
|
return PlainSymbol(symbols::PlainSymbol::new(name));
|
||||||
}
|
}
|
||||||
|
@ -887,6 +893,86 @@ fn test_utils_merge() {
|
||||||
test(&right, &left, &expected);
|
test(&right, &left, &expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! def_test_as_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_and_as_type_helper_functions() {
|
||||||
|
let max_i64 = i64::max_value().to_bigint().unwrap();
|
||||||
|
let bigger = &max_i64 * &max_i64;
|
||||||
|
|
||||||
|
let values = [
|
||||||
|
Value::Nil,
|
||||||
|
Value::Boolean(false),
|
||||||
|
Value::Integer(1i64),
|
||||||
|
Value::BigInteger(bigger),
|
||||||
|
Value::Float(OrderedFloat(22.22f64)),
|
||||||
|
Value::Text("hello world".to_string()),
|
||||||
|
s_plain("$symbol"),
|
||||||
|
s_ns("$ns", "$symbol"),
|
||||||
|
k_plain("hello"),
|
||||||
|
k_ns("hello", "world"),
|
||||||
|
Value::Vector(vec![Integer(1)]),
|
||||||
|
Value::List(LinkedList::from_iter(vec![])),
|
||||||
|
Value::Set(BTreeSet::from_iter(vec![])),
|
||||||
|
Value::Map(BTreeMap::from_iter(vec![
|
||||||
|
(Value::Text("a".to_string()), Value::Integer(1)),
|
||||||
|
])),
|
||||||
|
];
|
||||||
|
|
||||||
|
for i in 0..values.len() {
|
||||||
|
let value = &values[i];
|
||||||
|
|
||||||
|
let is_result = [
|
||||||
|
value.is_nil(),
|
||||||
|
value.is_boolean(),
|
||||||
|
value.is_integer(),
|
||||||
|
value.is_big_integer(),
|
||||||
|
value.is_float(),
|
||||||
|
value.is_text(),
|
||||||
|
value.is_symbol(),
|
||||||
|
value.is_namespaced_symbol(),
|
||||||
|
value.is_keyword(),
|
||||||
|
value.is_namespaced_keyword(),
|
||||||
|
value.is_vector(),
|
||||||
|
value.is_list(),
|
||||||
|
value.is_set(),
|
||||||
|
value.is_map(),
|
||||||
|
];
|
||||||
|
|
||||||
|
for j in 0..values.len() {
|
||||||
|
assert_eq!(j == i, is_result[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == 0 { assert_eq!(value.as_nil().unwrap(), ()) }
|
||||||
|
else { 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);
|
||||||
|
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_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_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_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)),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Handy templates for creating test cases follow:
|
// Handy templates for creating test cases follow:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue