valid_toml 0.0.2

Provides the ability to load a TOML file with validation.
Documentation
/* Copyright 2016 Joshua Gentry
 *
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 * http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 * <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 * option. This file may not be copied, modified, or distributed
 * except according to those terms.
 */
use std::fmt::{Display, Formatter, Error};

use enums::FormatDesc;

//*************************************************************************************************
/// Holds a validation error.  A validation error occurs when a value is defined in the TOML file
/// but does not match the rules defined for that value.
#[derive(Debug)]
pub enum ValidationError
{
    //---------------------------------------------------------------------------------------------
    /// A value could not be parsed, contains an optional error describing the parse error.
    CannotParse(Option<FormatDesc>),

    //---------------------------------------------------------------------------------------------
    /// A duration value is too large.  Contains the min/max lengths, the second value (max) will
    /// be defined, the min size may or may not be defined.
    DurationOverflow(Option<String>, Option<String>),

    //---------------------------------------------------------------------------------------------
    /// A duration value is too small.  Contains the min/max lengths, the fiurst value (min) will
    /// be defined, the max size may or may not be defined.
    DurationUnderrun(Option<String>, Option<String>),

    //---------------------------------------------------------------------------------------------
    /// A value is not the correct type and could not be read.  The supplied value is the expected
    /// data type.
    IncorrectType(&'static str),

    //---------------------------------------------------------------------------------------------
    /// A string value is too long.  Contains the min/max lengths, the second value (max) will
    /// be defined, the min size may or may not be defined.
    Long(Option<usize>, Option<usize>),

    //---------------------------------------------------------------------------------------------
    /// A numeric value is too large.  Contains the limits for the number, the second value (max)
    /// will be defined, the first value may or may not be defined.
    Overflow(Option<i64>, Option<i64>),

    //---------------------------------------------------------------------------------------------
    /// A string value is too short.  Contains the min/max lengths, the first value (min) will
    /// be defined, the max size may or may not be defined.
    Short(Option<usize>, Option<usize>),

    //---------------------------------------------------------------------------------------------
    /// A numeric value is too small.  Contains the limits for the number, the first value (min)
    /// will be defined, the second value may or may not be defined.
    Underrun(Option<i64>, Option<i64>)
}

impl Display for ValidationError
{
    //*********************************************************************************************
    /// Display a nice message for the warning.
    fn fmt(
        &self,
        fmt : &mut Formatter
        ) -> Result<(), Error>
    {
        match *self
        {
            ValidationError::CannotParse(ref desc) => {
                if let Some(desc) = desc.as_ref()
                {
                    write!(fmt, "{}", desc)
                }
                else
                {
                    write!(fmt, "Could not be parsed.")
                }
            },
            ValidationError::DurationOverflow(ref min, ref max) => {
                let max = max.as_ref().unwrap();

                if let Some(min) = min.as_ref()
                {
                    write!(fmt, "Duration must be between {} and {}, inclusive.", min, max)
                }
                else
                {
                    write!(fmt, "Duration must be less than or equal to {}.", max)
                }
            },
            ValidationError::DurationUnderrun(ref min, ref max) => {
                let min = min.as_ref().unwrap();

                if let Some(max) = max.as_ref()
                {
                    write!(fmt, "Duration must be between {} and {}, inclusive.", min, max)
                }
                else
                {
                    write!(fmt, "Duration must be greater than or equal to {}.", min)
                }
            },
            ValidationError::IncorrectType(data) => {
                write!(fmt, "Type must be a {}.", data)
            },
            ValidationError::Long(ref min, ref max) => {
                let max = max.as_ref().unwrap();

                if let Some(min) = min.as_ref()
                {
                    write!(fmt, "String length must be between {} and {}, inclusive.", min, max)
                }
                else
                {
                    write!(fmt, "String length must be less than or equal to {}.", max)
                }
            },
            ValidationError::Overflow(ref min, ref max) => {
                let max = max.as_ref().unwrap();

                if let Some(min) = min.as_ref()
                {
                    write!(fmt, "Value must be between {} and {}, inclusive.", min, max)
                }
                else
                {
                    write!(fmt, "Value must be less than or equal to {}.", max)
                }
            },
            ValidationError::Short(ref min, ref max) => {
                let min = min.as_ref().unwrap();

                if let Some(max) = max.as_ref()
                {
                    write!(fmt, "String length must be between {} and {}, inclusive.", min, max)
                }
                else
                {
                    write!(fmt, "String length must be greater than or equal to {}.", min)
                }
            },
            ValidationError::Underrun(ref min, ref max) => {
                let min = min.as_ref().unwrap();

                if let Some(max) = max.as_ref()
                {
                    write!(fmt, "Value must be between {} and {}, inclusive.", min, max)
                }
                else
                {
                    write!(fmt, "Value must be greater than or equal to {}.", min)
                }
            }
        }
    }
}