ommui_string_patterns 0.1.2

String pattern checkers for OMMUI identifiers
Documentation
//! For (de-)serializing ommui id strings which may be empty.
//!
//! See [`idstring`](../idstring/index.html) for a description of
//! ommui id strings.

use regex::Regex;
use serde::de;
use serde::ser;
use std::fmt;

pub fn is_valid(s: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new(r"^([A-Za-z][0-9A-Za-z_]*)?$").unwrap();
    }
    RE.is_match(s)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: de::Deserializer<'de>,
{
    struct FieldVisitor;

    impl<'de> de::Visitor<'de> for FieldVisitor {
        type Value = String;

        fn expecting(
            &self,
            formatter: &mut fmt::Formatter,
        ) -> fmt::Result {
            formatter.write_str("an id string")
        }

        fn visit_str<E>(self, value: &str) -> Result<String, E>
        where
            E: de::Error,
        {
            if is_valid(value) {
                Ok(value.to_string())
            } else {
                Err(de::Error::invalid_value(
                    de::Unexpected::Str(value),
                    &self,
                ))
            }
        }
    }

    deserializer.deserialize_string(FieldVisitor)
}

pub fn serialize<S>(s: &str, serializer: S) -> Result<S::Ok, S::Error>
where
    S: ser::Serializer,
{
    if is_valid(s) {
        serializer.serialize_str(s)
    } else {
        Err(ser::Error::custom("regex does not match"))
    }
}
#[cfg(test)]
mod tests {
    #[test]
    fn is_valid() {
        assert!(super::is_valid("AnIdString"));
        assert!(super::is_valid("AnotherIdString"));
        assert!(super::is_valid("anId2"));
        assert!(super::is_valid("anId2"));
        assert!(super::is_valid("anId2_"));
        assert!(super::is_valid("anId_2"));
        assert!(super::is_valid("an_Id2"));
        assert!(super::is_valid(""));
        assert!(!super::is_valid(" "));
        assert!(!super::is_valid("AnotherIdString "));
        assert!(!super::is_valid(" AnotherIdString"));
        assert!(!super::is_valid(" AnotherIdString "));
        assert!(!super::is_valid("1AnotherIdString"));
        assert!(!super::is_valid("_AnotherIdString"));
    }
}