lib-ruby-parser-nodes 0.37.0

Ruby parser nodes data
Documentation
use crate::template::{render::Render, Buffer, Parse, TemplateFns};

#[derive(Debug, PartialEq)]
pub struct List<Item> {
    parts: Vec<Item>,
}

impl<Item> List<Item> {
    pub(crate) fn new<V>(parts: V) -> Self
    where
        V: Into<Vec<Item>>,
    {
        Self {
            parts: parts.into(),
        }
    }
}

impl<Item> Parse for List<Item>
where
    Item: Parse + std::fmt::Debug,
{
    fn parse(buffer: &mut Buffer) -> Option<Self> {
        let mut parts = vec![];
        while !buffer.is_eof() {
            if let Some(part) = Item::parse(buffer) {
                parts.push(part)
            } else {
                break;
            }
        }
        if parts.is_empty() {
            None
        } else {
            Some(Self::new(parts))
        }
    }
}

impl<Item, Context> Render<Context> for List<Item>
where
    Item: Render<Context>,
{
    fn render(&self, ctx: &Context, fns: &TemplateFns) -> String {
        self.parts
            .iter()
            .map(|item| item.render(ctx, fns))
            .collect::<Vec<_>>()
            .join("")
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::template::{global_context::NO_DATA, shards::Char};

    type CharList = List<Char>;

    #[test]
    fn test_parse() {
        let mut buffer = Buffer::new("abc".as_bytes().to_vec());
        let parsed = CharList::parse(&mut buffer).unwrap();

        assert_eq!(
            parsed,
            CharList::new([Char { c: 'a' }, Char { c: 'b' }, Char { c: 'c' }])
        )
    }

    #[test]
    fn test_render() {
        let list = CharList::new([Char { c: 'a' }, Char { c: 'b' }, Char { c: 'c' }]);
        let fns = TemplateFns::new();
        assert_eq!(
            "stored char a\nstored char b\nstored char c\n",
            list.render(NO_DATA, &fns)
        )
    }
}