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());
}
}
|