use toml::Value;
use data::Container;
use enums::ExtractResult;
use item_def::ItemDef;
use item_value::ItemValue;
use toml_def::TomlDef;
use value::StringValue;
pub struct ItemStr
{
name : String,
min : Option<usize>,
max : Option<usize>,
optional : bool,
default : Option<String>
}
impl ItemStr
{
pub fn with_name<T:AsRef<str>>(name : T) -> ItemStr
{
ItemStr {
name : String::from(name.as_ref()),
min : None,
max : None,
optional : false,
default : None
}
}
pub fn add_to(
self,
group : &mut TomlDef
) -> StringValue
{
let notify = StringValue::new();
group.add_notify(self.name.clone(), Box::new(notify.clone()));
group.ref_add(self);
notify
}
pub fn min(
mut self,
min : usize
) -> Self
{
self.min = Some(min);
self
}
pub fn max(
mut self,
max : usize
) -> Self
{
self.max = Some(max);
self
}
pub fn optional(
mut self,
) -> Self
{
self.optional = true;
self
}
pub fn default<T:AsRef<str>>(
mut self,
default : T
) -> Self
{
self.default = Some(String::from(default.as_ref()));
self
}
}
impl ItemDef for ItemStr
{
fn name(&self) -> &str
{
&self.name
}
fn extract(
&self,
value : &Value
) -> ExtractResult
{
if let Some(value) = value.as_str()
{
if let Some(min) = self.min
{
if value.len() < min
{
return ExtractResult::short(self.min.clone(), self.max.clone())
}
}
if let Some(max) = self.max
{
if value.len() > max
{
return ExtractResult::long(self.min.clone(), self.max.clone())
}
}
ExtractResult::Item(ItemValue::String(String::from(value)))
}
else
{
ExtractResult::incorrect_type("number")
}
}
fn is_optional(&self) -> bool
{
self.optional
}
fn default(&self) -> Option<ItemValue>
{
self.default.as_ref().map(|x|ItemValue::String(x.clone()))
}
}
#[cfg(test)]
mod tests
{
use toml::Value;
use item_def::ItemDef;
use item_value::ItemValue;
use enums::{ExtractResult, ValidationError};
macro_rules! test {
($item:expr, $val:expr) => ($item.extract(&Value::String(String::from($val))))
}
#[test]
fn set()
{
super::ItemStr::with_name("a").min(12);
super::ItemStr::with_name("b").max(67);
super::ItemStr::with_name("c").default("abc");
}
#[test]
fn min()
{
let test = super::ItemStr::with_name("b").min(4);
assert_short!(test!(test, "ab"), 4);
assert_string!(test!(test, "abcd"), "abcd");
assert_string!(test!(test, "abcdef"), "abcdef");
}
#[test]
fn max()
{
let test = super::ItemStr::with_name("b").max(4);
assert_string!(test!(test, "abcd"), "abcd");
assert_string!(test!(test, ""), "");
assert_long!(test!(test, "abcdef"), 4);
}
#[test]
fn min_max()
{
let test = super::ItemStr::with_name("b").min(2).max(4);
assert_short!(test!(test, ""), 2, 4);
assert_string!(test!(test, "ab"), "ab");
assert_string!(test!(test, "abc"), "abc");
assert_string!(test!(test, "abcd"), "abcd");
assert_long!(test!(test, "abcde"), 2, 4);
}
}