use crate::utils::Number; use crate::{Map, Value}; impl From> for Value where V: Into, { fn from(v: Map<&str, V>) -> Self { let mut map: Map = Map::new(); for (key, value) in v.into_iter() { map.insert(key.to_string(), value.into()); } Self::Object(map) } } impl From for Value { fn from(number: Number) -> Self { Value::Number(number) } } impl From> for Value { fn from(_: Option<()>) -> Self { Self::Null } } impl From> for Value where T: Into, { fn from(v: Vec) -> Self { let mut vec: Vec = Vec::new(); for item in v { vec.push(item.into()); } Self::Array(vec) } } macro_rules! from_ { ($ident:ty, $value:ident) => { impl From<$ident> for Value { fn from(v: $ident) -> Self { Self::$value(v.into()) } } }; } macro_rules! from_as { ($ident:ty, $as:ty, $value:ident) => { impl From<$ident> for Value { fn from(v: $ident) -> Self { Self::$value(Number::from((v as $as).into()).unwrap()) } } }; } from_! {bool, Boolean} from_! {i8, Number} from_! {i16, Number} from_! {i32, Number} from_! {u8, Number} from_! {u16, Number} from_! {u32, Number} from_as! {isize, f64, Number} from_as! {usize, f64, Number} impl From<&str> for Value { fn from(v: &str) -> Self { Self::String(v.to_string()) } } impl From for Value { fn from(v: std::string::String) -> Self { Self::String(v.to_string()) } } impl From<&std::string::String> for Value { fn from(v: &std::string::String) -> Self { Self::String(v.to_string()) } } #[cfg(test)] mod tests { use crate::map; use crate::utils::Number; use crate::{Map, Value}; #[test] fn it_implements_from_map() { let map = map!("foo" => "bar"); assert!(matches!(map.into(), Value::Object(..))); } #[test] fn it_implements_from_number() { let number = Number::from(42.0).unwrap(); assert!(matches!(number.into(), Value::Number(..))); } #[test] fn it_implements_from_vec() { let vec = vec![1, 2]; assert!(matches!(vec.into(), Value::Array(..))); } #[test] fn it_implements_from_vecref() { let text = "foo".to_string(); let vec = vec![&text]; assert!(matches!(vec.into(), Value::Array(..))); } #[test] fn it_implements_from_refvec() { let vec = vec![1, 2]; assert!(matches!(&vec.into(), Value::Array(..))); } #[test] fn it_implements_from_refvecref() { let text = "foo".to_string(); let vec = vec![&text]; assert!(matches!(vec.into(), Value::Array(..))); } #[test] fn it_implements_from_bool() { assert!(matches!(true.into(), Value::Boolean(true))); assert!(matches!(false.into(), Value::Boolean(false))); } #[test] fn it_implements_from_null() { assert!(matches!(None.into(), Value::Null)); assert!(matches!(Some(()).into(), Value::Null)); } macro_rules! from_int { ($ident:ident, $expected:expr, $type:ty, $input:expr) => { #[test] fn $ident() { let value: Value = $input.into(); assert_eq!($expected, value.as_f64().unwrap()) } }; } from_int!(it_implements_from_u8, 42.0, u8, 42u8); from_int!(it_implements_from_u16, 42.0, u16, 42u16); from_int!(it_implements_from_u32, 42.0, u32, 42u32); from_int!(it_implements_from_usize, 42.0, usize, 42usize); from_int!(it_implements_from_i8, 42.0, i8, 42i8); from_int!(it_implements_from_i16, 42.0, i16, 42i16); from_int!(it_implements_from_i32, 42.0, i32, 42i32); from_int!(it_implements_from_isize, 42.0, isize, 42isize); #[test] fn it_implements_from_refstr() { let str = "foo"; assert!(matches!(str.into(), Value::String(..))); } #[test] fn it_implements_from_string() { let str = "foo".to_string(); assert!(matches!(str.into(), Value::String(..))); } #[test] fn it_implements_from_refstring() { let str = "foo".to_string(); assert!(matches!(&str.into(), Value::String(..))); } }