use kdl::KdlValue; use serde_kdl::{Node, Value}; use serde_test::{assert_tokens, Token}; pub fn value_as_token(v: Value) -> Token { match v.0 { KdlValue::Int(i) => Token::I64(i), KdlValue::Float(f) => Token::F64(f), KdlValue::String(s) => Token::Str(Box::leak(s.into_boxed_str())), KdlValue::Boolean(b) => Token::Bool(b), KdlValue::Null => Token::Unit, } } pub fn get_nodes(document: &str) -> Vec { kdl::parse_document(document) .unwrap() .into_iter() .map(Node) .collect() } pub fn assert_all_tokens(document: &str, tokens: &[&[Token]]) { let nodes = get_nodes(document); for (node, tokens) in nodes.iter().zip(tokens.iter()) { assert_tokens(node, tokens); } } macro_rules! count { () => (0usize); ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); } macro_rules! value_tokens { ($value:expr) => {{ let value = ::serde_kdl::Value(::kdl::KdlValue::from($value)); $crate::utils::value_as_token(value) }}; } macro_rules! node_tokens { { name: $name:expr $(, values: [ $($value:expr $(,)? )* ] )? $(, properties: { $($pk:literal => $pv:expr $(,)? )* } )? $(, children: [ $( $child:tt $(,)? )* ] $(,)? )? $(,)? } => {{ todo!("optional values") }}; { name: $name:expr, values: [ $($value:expr $(,)? )* ], properties: { $($pk:literal => $pv:expr $(,)? )* }, children: [ $( $child:tt $(,)? )* ] $(,)? } => {{ use ::serde_test::Token; &[ Token::Struct { name: "Node", len: 4, }, Token::Str("name"), Token::Str($name), Token::Str("values"), Token::Seq { len: Some(count!($($value)*)) }, $(value_tokens!($value),)* Token::SeqEnd, Token::Str("properties"), Token::Map { len: Some(count!($($pk)*)) }, $(Token::Str($pk), value_tokens!($pv),)* Token::MapEnd, Token::Str("children"), Token::Seq { len: Some(count!($($child)*)) }, $(node_tokens!($child),)* Token::SeqEnd, Token::StructEnd, ] }}; }