Skip to content

Instantly share code, notes, and snippets.

@flying-sheep
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flying-sheep/f2afd381d07ee5d2bbbe to your computer and use it in GitHub Desktop.
Save flying-sheep/f2afd381d07ee5d2bbbe to your computer and use it in GitHub Desktop.
#![feature(macro_rules)]
use std::fmt;
trait Element {}
macro_rules! Elem(
($name:ident { $($element:ident: $ty:ty),* }) => (
struct $name {
$(
$element: $ty
),*
}
impl $name {
fn name() -> &'static str { stringify!($name) }
}
impl Element for $name {}
impl fmt::Show for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{0}/>", stringify!($name))
}
}
);
($name:ident $subname:ident[ $($child:ident),+ ] { $($element:ident: $ty:ty),* }) => (
trait $subname: fmt::Show {}
impl<'a> fmt::Show for Box<$subname + 'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", *self) //TODO: abc instead of [a,b,c]
}
}
$(
impl $subname for $child {}
)+
struct $name<'a> {
children: Vec<Box<$subname + 'a>>,
$(
$element: $ty
),*
}
impl<'a> $name<'a> {
fn name() -> &'static str { stringify!($name) }
}
impl<'a> Element for $name<'a> {}
impl<'a> fmt::Show for $name<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{0}>{1}</{0}>", stringify!($name), self.children)
}
}
)
)
Elem!(Text { text: String })
Elem!(Header __SubHeader[Text] { })
fn main() {
let mut h = Header { children: vec![] };
h.children.push(box Text { text: "Hio".to_string() });
println!("{}", h);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment