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
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ImageRef {
pub registry: Option<String>,
pub image: String,
pub tag: Option<String>
}
fn is_registry(token: &str) -> bool {
token == "localhost" || token.contains('.') || token.contains(':')
}
impl ImageRef {
pub fn parse(s: &str) -> ImageRef {
let parts: Vec<&str> = s.splitn(2, '/').collect();
let (registry, image_full) = if parts.len() == 1 {
(None, parts[0])
} else if is_registry(parts[0]) {
(Some(parts[0].to_string()), parts[1])
} else {
(None, parts[0])
};
let parts: Vec<&str> = image_full.splitn(2, ':').collect();
let image = parts[0].to_string();
let tag = parts.get(1).map(|p| String::from(*p));
ImageRef { registry, image, tag }
}
}
impl fmt::Display for ImageRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(registry) = &self.registry {
write!(f, "{}/", registry)?;
}
write!(f, "{}", self.image)?;
if let Some(tag) = &self.tag {
write!(f, ":{}", tag)?;
}
Ok(())
}
}