mdbook-journal 0.4.0

journal plugin for mdBook
Documentation
use super::*;

#[derive(Default)]
struct Parts {
    len: usize,
    buffers: Vec<String>,
}

impl Parts {
    fn load(&mut self, path: PathBuf) -> Result<()> {
        self.clear();
        self.prepare_size(path.components().count());
        for (idx, part) in path.components().enumerate() {
            let str_part = part
                .as_os_str()
                .to_str()
                .with_context(|| format!("converting segment for index [{}]", path.display()))?;
            let buffer = &mut self.buffers[idx];
            buffer.push_str(str_part);
        }
        Ok(())
    }

    fn clear(&mut self) {
        self.len = 0;
        self.buffers.iter_mut().for_each(String::clear);
    }

    fn prepare_size(&mut self, size: usize) {
        let current = self.buffers.len();
        if current < size {
            for _ in current..size {
                self.buffers.push(String::with_capacity(128));
            }
        }
        self.len = size;
    }

    fn iter_mut(&mut self) -> impl Iterator<Item = &mut String> {
        self.buffers[0..(self.len)].iter_mut()
    }

    fn iter(&self) -> impl Iterator<Item = &String> {
        self.buffers[0..(self.len)].iter()
    }
}

pub struct TopicParts<'a> {
    topic: &'a Topic,
    parts: Parts,
}

impl<'a> TopicParts<'a> {
    pub fn new(topic: &'a Topic) -> Self {
        Self {
            topic,
            parts: Default::default(),
        }
    }

    pub fn load(&mut self, entry: &Entry) -> Result<()> {
        let mut path = self.topic.virtual_path(entry)?;
        path.pop();
        self.parts.load(path)?;
        Ok(())
    }

    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut String> {
        self.parts.iter_mut()
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::support::fixtures::*;
    use crate::support::prelude::*;

    #[rstest]
    fn topic_parts_iter_functions_correctly(topic: Topic, entry: Entry) -> Result<()> {
        let mut parts = TopicParts::new(&topic);
        parts.load(&entry)?;
        let segments: Vec<String> = parts.iter_mut().map(|p| p.clone()).collect();
        assert_eq!(&vec!["test", "2024", "July"], &segments[..]);
        Ok(())
    }
}