~genbyte/bempline

245df27d9f89ac3ae4cb06fbfc5cb9aa4c93e23d — genuinebyte a month ago ad8bac0
Add doc comments and error enum
3 files changed, 98 insertions(+), 7 deletions(-)

M src/document.rs
A src/error.rs
M src/lib.rs
M src/document.rs => src/document.rs +56 -7
@@ 1,4 1,5 @@
use crate::elements::Element;
use crate::error::Error;
use std::fs;

pub struct Document {


@@ 12,6 13,20 @@ impl Document {
        }
    }

    /// Returns a usize indicating how many variables were replaced
    ///
    /// Replace every instance of variable `key` with text `value`
    ///
    /// # Example
    /// ```rust
    /// use bempline::Document;
    ///
    /// let mut doc = Document::new("Hello, {~ $noun ~}!");
    /// let num_replaced = doc.set_variable("noun", "World");
    ///
    /// assert_eq!(num_replaced, 1);
    /// assert_eq!(doc.as_string(), "Hello, World!");
    /// ```
    pub fn set_variable(&mut self, key: &str, value: &str) -> usize {
        let compare = |element: &Element| match element {
            Element::Variable(vkey) if vkey == key => true,


@@ 30,7 45,18 @@ impl Document {
        }
    }

    pub fn process_includes(&mut self) -> Result<usize, ()> {
    /// Returns a usize indicating the number of includes that were processed
    /// successfully.
    ///
    /// Replaces every include command in the document with the content of the
    /// file it references.
    ///
    /// # Errors
    /// Returns a [`Error`] if a file referenced by one of the include
    /// statements is unable to be opened for reading.
    ///
    /// [`Error`]: enum.Error.html
    pub fn process_includes(&mut self) -> Result<usize, Error> {
        let compare = |element: &Element| match element {
            Element::Include(_) => true,
            _ => false


@@ 44,8 70,7 @@ impl Document {
                    _ => unreachable!()
                };

                //TODO: Handle errors correctly
                let contents = fs::read_to_string(filename).unwrap();
                let contents = fs::read_to_string(filename)?;
                self.elements.remove(index);

                let include_elements = Element::parse_elements(&contents);


@@ 60,7 85,16 @@ impl Document {
        }
    }

    pub fn get_pattern(&self, name: &str) -> Result<Document, ()> {
    /// Returns a [`Document`] of the elements in the pattern
    ///
    /// Retreives the pattern `name`
    ///
    /// # Errors
    /// Returns a [`Error`] if the pattern does not exist.
    ///
    /// [`Error`]: enum.Error.html
    /// [`Document`]: struct.Document.html
    pub fn get_pattern(&self, name: &str) -> Result<Document, Error> {
        let compare = |element: &&Element| match element {
            Element::Pattern(pname, _) if pname == name => true,
            _ => false,


@@ 74,10 108,21 @@ impl Document {
            }
        }

        Err(())
        Err(Error::BadPattern(name.to_string()))
    }

    pub fn set_pattern(&mut self, name: &str, pattern: Document) -> Result<usize, ()> {
    /// Returns a usize indicating how many elements were inserted into the
    /// document.
    ///
    /// Inserts the elementa from `pattern` into this document, before the
    /// pattern `name`
    ///
    /// # Errors
    /// Returns a [`Error`] if the pattern does
    /// not exist.
    ///
    /// [`Error`]: enum.Error.html
    pub fn set_pattern(&mut self, name: &str, pattern: Document) -> Result<usize, Error> {
        let compare = |element: &Element| match element {
            Element::Pattern(pname, _) if pname == name => true,
            _ => false,


@@ 93,9 138,13 @@ impl Document {
            return Ok(elements_inserted);
        }

        Err(())
        Err(Error::BadPattern(name.to_string()))
    }

    /// Returns a string of this document.
    ///
    /// Only text is included in the string. No variables, unproccesed includes,
    /// or patterns will be in the string.
    pub fn as_string(self) -> String {
        let mut string = String::new();


A src/error.rs => src/error.rs +40 -0
@@ 0,0 1,40 @@
use std::error::Error as ErrorTrait;
use std::io::Error as IOError;
use std::fmt;

/// Errors that can be encountered when calling functions on a [`Document`]
///
/// [`Document`]: struct.Document.html
#[derive(Debug)]
pub enum Error {
    /// Container for an [`io::Error`]
    ///
    /// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
    IOError(IOError),
    /// The pattern could not be found
    BadPattern(String),
}

impl ErrorTrait for Error {
    fn source(&self) -> Option<&(dyn ErrorTrait + 'static)> {
        match self {
            Error::IOError(ioe) => Some(ioe),
            _ => None
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::IOError(ioe) => ioe.fmt(f),
            Error::BadPattern(name) => write!(f, "The pattern {} does not exist", name)
        }
    }
}

impl From<IOError> for Error {
    fn from(ioe: IOError) -> Self {
        Error::IOError(ioe)
    }
}

M src/lib.rs => src/lib.rs +2 -0
@@ 1,4 1,6 @@
mod document;
mod elements;
mod error;

pub use document::Document;
pub use error::Error;