dialtone_sqlx 0.1.0

Dialtone SQLx Back-End
Documentation
use chrono::{DateTime, SecondsFormat, Utc};
use regex::Regex;

lazy_static! {
    static ref URL_SAFE_REPLACE_RE: Regex = Regex::new("[\\W_,]").unwrap();
}

pub fn make_local_id(pun: Option<&str>, title: Option<&str>) -> String {
    let title = match title {
        None => dt_dt(Utc::now()),
        Some(t) => format!("{},{}", make_url_safe(t), Utc::now().timestamp()),
    };
    match pun {
        None => title,
        Some(p) => {
            format!("{},{}", p, title)
        }
    }
}

/// This function contains the logic for creating dialtone stylized
/// datetimes used in ids for activity pub objects. They are simply
/// datetimes that work in URLs without percent encodings by escaping
/// known characters with other known characters that would not appear
/// in datetime RFC3333 formatted output.
fn dt_dt(dt: DateTime<Utc>) -> String {
    let s = dt.to_rfc3339_opts(SecondsFormat::Millis, true);
    s.replace(":", "c")
}

pub fn make_url_safe(title: &str) -> String {
    URL_SAFE_REPLACE_RE.replace_all(title, "-").to_string()
}

#[cfg(test)]
mod local_id_tests {
    use super::*;
    use chrono::{TimeZone, Utc};

    #[test]
    fn make_local_id_test() {
        assert!(make_local_id(Some("foo"), None).starts_with("foo,"));
        assert!(!make_local_id(None, None).starts_with("foo,"));

        let s = make_local_id(Some("foo"), Some("she sells seashells"));
        assert!(s.starts_with("foo,"));
        assert!(s.contains("she-sells-seashells"));

        let s = make_local_id(None, Some("she sells seashells"));
        assert!(!s.starts_with("foo,"));
        assert!(s.contains("she-sells-seashells"));
    }

    #[test]
    fn dt_dt_test() {
        let dt = Utc.ymd(2018, 1, 26).and_hms_micro(18, 30, 9, 453_829);
        assert_eq!(dt_dt(dt), "2018-01-26T18c30c09.453Z");
    }

    #[test]
    fn make_url_safe_test() {
        let s = make_url_safe("foo bar:baz,bug");
        assert_eq!(s, "foo-bar-baz-bug")
    }
}