summaryrefslogtreecommitdiffstats
path: root/src/util/mod.rs
blob: 84ea1140df33bcb07a0c081baca5b6117271a45f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use serde::Deserialize;

#[derive(Deserialize, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct EnvironmentVariableName(String);

pub mod docker {
    use anyhow::Result;
    use anyhow::anyhow;
    use serde::Deserialize;

    #[derive(Deserialize, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
    pub struct ImageName(String);

    /// Check whether a string is a valid docker tag name
    ///
    /// From the docker spec:
    ///
    /// > A tag name must be valid ASCII and may contain lowercase and uppercase letters, digits,
    /// > underscores, periods and dashes. A tag name may not start with a period or a dash and may
    /// > contain a maximum of 128 characters.
    ///
    /// Returns Ok(()) if `s` is a valid docker tag name, otherwise an explanatory error message
    pub fn is_valid_tag_name(s: &str) -> Result<()> {
        let valid_chars = s.chars().all(|c| {
            c == '_' ||
            c == ':' ||
            c == '-' ||
            c.is_ascii_alphanumeric()
        });

        if !valid_chars {
            return Err(anyhow!("Invalid characters"))
        }

        if s.chars().count() > 128 {
            return Err(anyhow!("Too long"))
        }


        if s.chars().next().map(|c| c == '.' || c == '-').unwrap_or(false) {
            return Err(anyhow!("Starts with invalid character"))
        }

        Ok(())
    }
}

#[cfg(test)]
mod docker_test {
    extern crate env_logger;
    fn setup_logging() {
        let _ = env_logger::try_init();
    }

    use super::docker::*;

    #[test]
    fn is_valid_tag_name_test_1() {
        setup_logging();
        let test = |s| {
            debug!("check if valid: '{}'", s);
            let e = is_valid_tag_name(s);
            debug!("Result = {:?}", e);
            e
        };

        assert!(test("foo").is_ok());
        assert!(test("foo:bar").is_ok());
        assert!(test("foo123").is_ok());
        assert!(test("1f23oo").is_ok());
        assert!(test(":foo").is_ok());
        assert!(test(".foo").is_err());
        assert!(test("-foo").is_err());
    }

}