ommui_string_patterns 0.1.2

String pattern checkers for OMMUI identifiers
Documentation
//! For (de-)serializing ommui freetext strings which may be empty.
//!
//! See [`freetextstring`](../freetextstring/index.html) for a description of
//! ommui freetext 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"^(\S+(?:.*\S)?)?$").unwrap();
    }
    RE.is_match(s)
}

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

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

        fn expecting(
            &self,
            formatter: &mut fmt::Formatter,
        ) -> fmt::Result {
            formatter.write_str("a freetext 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("AFreetextString"));
        assert!(super::is_valid("A Freetext String"));
        assert!(super::is_valid("Another Freetext String!"));
        assert!(super::is_valid("_Another Freetext String"));
        assert!(super::is_valid("1 Another FreetextString"));
        assert!(super::is_valid(""));
        assert!(!super::is_valid(" "));
        assert!(!super::is_valid("Another Freetext String "));
        assert!(!super::is_valid(" Another Freetext String"));
        assert!(!super::is_valid(" Another FreetextString "));
        assert!(!super::is_valid("Another Freetext String "));
        assert!(!super::is_valid(" Another Freetext String"));
        assert!(!super::is_valid(" Another Freetext String "));
        assert!(!super::is_valid("1 Another Freetext String "));
        assert!(!super::is_valid(" _Another Freetext String"));
    }
}