tanzim-validate 0.8.0

Validate and coerce tanzim-value configuration trees
Documentation
use crate::error::{Error, ErrorKind};
use crate::{Meta, Validator};
use tanzim_value::{Value, ValueType};

/// (`regex` feature) Accepts a string that is itself a valid regular expression.
#[derive(Debug, Clone, Default)]
pub struct RegexPattern {
    meta: Meta,
}

impl RegexPattern {
    pub fn new() -> Self {
        Self::default()
    }

    /// Attach human-facing metadata (name, description, examples, default, output conversion).
    pub fn with_meta(mut self, meta: Meta) -> Self {
        self.meta = meta;
        self
    }
}

crate::impl_meta_methods!(RegexPattern);

impl Validator for RegexPattern {
    fn meta(&self) -> &Meta {
        &self.meta
    }

    fn meta_mut(&mut self) -> &mut Meta {
        &mut self.meta
    }

    fn check(&self, value: &mut Value) -> Result<(), Error> {
        let text = match value {
            Value::String(text) => text,
            other => {
                return Err(Error::new(ErrorKind::Type {
                    expected: ValueType::String,
                    found: other.type_name(),
                }));
            }
        };
        match regex::Regex::new(text) {
            Ok(_) => Ok(()),
            Err(_) => Err(Error::new(ErrorKind::Format {
                expected: "regular expression",
            })),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn accepts_valid_and_rejects_invalid() {
        assert!(
            RegexPattern::new()
                .validate(&mut Value::String("^a.*$".into()))
                .is_ok()
        );
        assert!(
            RegexPattern::new()
                .validate(&mut Value::String("(".into()))
                .is_err()
        );
    }
}