teo-parser 0.3.0

Parser for Teo schema language
Documentation
#[macro_export]
macro_rules! declare_node {
    ($struct_name:ident) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: crate::ast::span::Span,
            pub(crate) path: Vec<usize>,
        }
    };
    ($struct_name:ident, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: crate::ast::span::Span,
            pub(crate) path: Vec<usize>,
            $($vis $element: $ty),*
        }
    };
}

#[macro_export]
macro_rules! declare_container_node {
    ($struct_name:ident) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: Span,
            pub(crate) path: Vec<usize>,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
        }
    };
    ($struct_name:ident, named) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: Span,
            pub(crate) path: Vec<usize>,
            pub(crate) string_path: Vec<String>,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
        }
    };
    ($struct_name:ident, availability) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: Span,
            pub(crate) path: Vec<usize>,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
            pub(crate) define_availability: crate::availability::Availability,
            pub(crate) actual_availability: std::cell::RefCell<crate::availability::Availability>,
        }
    };
    ($struct_name:ident, named, availability, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: crate::ast::span::Span,
            pub(crate) path: Vec<usize>,
            pub(crate) string_path: Vec<String>,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
            pub(crate) define_availability: crate::availability::Availability,
            pub(crate) actual_availability: std::cell::RefCell<crate::availability::Availability>,
            $($vis $element: $ty),*
        }
    };
    ($struct_name:ident, named, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: crate::ast::span::Span,
            pub(crate) path: Vec<usize>,
            pub(crate) string_path: Vec<String>,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
            $($vis $element: $ty),*
        }
    };
    ($struct_name:ident, availability, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: crate::ast::span::Span,
            pub(crate) path: Vec<usize>,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
            pub(crate) define_availability: crate::availability::Availability,
            pub(crate) actual_availability: std::cell::RefCell<crate::availability::Availability>,
            $($vis $element: $ty),*
        }
    };
    ($struct_name:ident, $($vis: vis $element: ident: $ty: ty),* $(,)?) => {
        #[derive(Debug)]
        pub struct $struct_name {
            pub(crate) span: crate::ast::span::Span,
            pub(crate) children: std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>,
            pub(crate) path: Vec<usize>,
            $($vis $element: $ty),*
        }
    };
}

#[macro_export]
macro_rules! impl_node_defaults {
    ($struct_name:ident) => {
        impl crate::traits::identifiable::Identifiable for $struct_name {
            fn path(&self) -> &Vec<usize> {
               &self.path
            }
        }
        impl crate::traits::node_trait::NodeTrait for $struct_name {
            fn span(&self) -> crate::ast::span::Span {
                self.span
            }
            fn children(&self) -> Option<&std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>> {
                None
            }
        }
        impl From<$struct_name> for crate::ast::node::Node {
            fn from(value: $struct_name) -> Self {
                crate::ast::node::Node::$struct_name(value)
            }
        }
        impl TryFrom<crate::ast::node::Node> for $struct_name {
            type Error = &'static str;
            fn try_from(value: crate::ast::node::Node) -> Result<Self, Self::Error> {
                match value {
                    crate::ast::node::Node::$struct_name(n) => Ok(n),
                    _ => Err("convert failed"),
                }
            }
        }
        impl<'a> TryFrom<&'a crate::ast::node::Node> for &'a $struct_name {
            type Error = &'static str;

            fn try_from(value: &'a crate::ast::node::Node) -> Result<Self, Self::Error> {
                match value {
                    crate::ast::node::Node::$struct_name(n) => Ok(n),
                    _ => Err("convert failed"),
                }
            }
        }
        impl std::fmt::Display for $struct_name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                f.write_str(&self.write_output_with_default_writer())
            }
        }
    };
}

#[macro_export]
macro_rules! impl_container_node_defaults {
    ($struct_name:ident) => {
        impl crate::traits::identifiable::Identifiable for $struct_name {
            fn path(&self) -> &Vec<usize> {
               &self.path
            }
        }
        impl crate::traits::node_trait::NodeTrait for $struct_name {
            fn span(&self) -> crate::ast::span::Span {
                self.span
            }
            fn children(&self) -> Option<&std::collections::btree_map::BTreeMap<usize, crate::ast::node::Node>> {
                Some(&self.children)
            }
        }
        impl From<$struct_name> for crate::ast::node::Node {
            fn from(value: $struct_name) -> Self {
                crate::ast::node::Node::$struct_name(value)
            }
        }
        impl TryFrom<crate::ast::node::Node> for $struct_name {
            type Error = &'static str;
            fn try_from(value: crate::ast::node::Node) -> Result<Self, Self::Error> {
                match value {
                    crate::ast::node::Node::$struct_name(n) => Ok(n),
                    _ => Err("convert failed"),
                }
            }
        }
        impl<'a> TryFrom<&'a crate::ast::node::Node> for &'a $struct_name {
            type Error = &'static str;

            fn try_from(value: &'a crate::ast::node::Node) -> Result<Self, Self::Error> {
                match value {
                    crate::ast::node::Node::$struct_name(n) => Ok(n),
                    _ => Err("convert failed"),
                }
            }
        }
        impl std::fmt::Display for $struct_name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                f.write_str(&self.write_output_with_default_writer())
            }
        }
    };
    ($struct_name:ident, named) => {
        impl_container_node_defaults!($struct_name);
        impl crate::traits::named_identifiable::NamedIdentifiable for $struct_name {
            fn string_path(&self) -> &Vec<String> {
                &self.string_path
            }
        }

    };
    ($struct_name:ident, availability) => {
        impl_container_node_defaults!($struct_name);
        impl crate::traits::has_availability::HasAvailability for $struct_name {
            fn define_availability(&self) -> crate::availability::Availability {
                self.define_availability
            }
            fn actual_availability(&self) -> crate::availability::Availability {
                *self.actual_availability.borrow()
            }
        }
    };
    ($struct_name:ident, named, availability) => {
        impl_container_node_defaults!($struct_name);
        impl crate::traits::named_identifiable::NamedIdentifiable for $struct_name {
            fn string_path(&self) -> &Vec<String> {
                &self.string_path
            }
        }
        impl crate::traits::has_availability::HasAvailability for $struct_name {
            fn define_availability(&self) -> crate::availability::Availability {
                self.define_availability
            }
            fn actual_availability(&self) -> crate::availability::Availability {
                *self.actual_availability.borrow()
            }
        }
    };
}

#[macro_export]
macro_rules! node_children_iter {
    ($struct_name:ident, $child_struct_name:ident, $iter_name:ident, $field_name:ident) => {
        pub struct $iter_name<'a> {
            index: usize,
            owner: &'a $struct_name,
        }
        impl<'a> Iterator for $iter_name<'a> {
            type Item = &'a $child_struct_name;
            fn next(&mut self) -> Option<Self::Item> {
                self.index += 1;
                self.owner.$field_name.get(self.index - 1).map(|i| self.owner.children.get(i).unwrap().try_into().unwrap())
            }
        }
    };
}

#[macro_export]
macro_rules! node_children_iter_fn {
    ($fn_name:ident, $iter_name:ident) => {
        pub fn $fn_name(&self) -> $iter_name {
            $iter_name {
                owner: self,
                index: 0,
            }
        }
    }
}

#[macro_export]
macro_rules! node_children_pair_iter {
    ($struct_name:ident, $child_struct_name:ident, $iter_name:ident, $field_name:ident) => {
        pub struct $iter_name<'a> {
            index: usize,
            owner: &'a $struct_name,
        }
        impl<'a> Iterator for $iter_name<'a> {
            type Item = (&'a $child_struct_name, &'a $child_struct_name);
            fn next(&mut self) -> Option<Self::Item> {
                self.index += 1;
                self.owner.$field_name.get(self.index - 1).map(|(k, v)| (self.owner.children.get(k).unwrap().try_into().unwrap(), self.owner.children.get(v).unwrap().try_into().unwrap()))
            }
        }
    };
}

#[macro_export]
macro_rules! node_child_fn {
    ($name:ident, $struct_type:ident) => {
        pub fn $name(&self) -> &$struct_type {
            self.children.get(&self.$name).unwrap().try_into().unwrap()
        }
    }
}

#[macro_export]
macro_rules! node_optional_child_fn {
    ($name:ident, $class:ident) => {
        pub fn $name(&self) -> Option<&$class> {
            if let Some(id) = self.$name {
                Some(self.children.get(&id).unwrap().try_into().unwrap())
            } else {
                None
            }
        }
    }
}