-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdocker_image.rs
More file actions
145 lines (125 loc) · 4.16 KB
/
docker_image.rs
File metadata and controls
145 lines (125 loc) · 4.16 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! Docker image reference value object
//!
//! This module provides a strongly-typed Docker image reference that combines
//! a repository name with a tag. It is used to represent Docker images in
//! service configurations and templates.
//!
//! # Design Decision
//!
//! Docker image versions are **not user-configurable** — they are pinned as
//! constants in the code to ensure compatibility between the deployer and the
//! images it uses. Exposing them through domain configs (rather than hardcoding
//! in templates) gives us:
//!
//! - A **single source of truth** for each image version
//! - The ability to **inspect images via the `show` command**
//! - Automatic propagation of version changes to both templates and CI scanning
//!
//! # Examples
//!
//! ```rust
//! use torrust_tracker_deployer_lib::shared::docker_image::DockerImage;
//!
//! let image = DockerImage::new("torrust/tracker", "develop");
//! assert_eq!(image.full_reference(), "torrust/tracker:develop");
//! assert_eq!(image.repository(), "torrust/tracker");
//! assert_eq!(image.tag(), "develop");
//! ```
use std::fmt;
use serde::{Deserialize, Serialize};
/// Docker image reference with repository and tag
///
/// Represents an image reference of the form `repository:tag`,
/// e.g. `torrust/tracker:develop` or `mysql:8.4`.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DockerImage {
repository: String,
tag: String,
}
impl DockerImage {
/// Creates a new Docker image reference
///
/// # Examples
///
/// ```rust
/// use torrust_tracker_deployer_lib::shared::docker_image::DockerImage;
///
/// let image = DockerImage::new("torrust/tracker", "develop");
/// assert_eq!(image.repository(), "torrust/tracker");
/// assert_eq!(image.tag(), "develop");
/// ```
#[must_use]
pub fn new(repository: impl Into<String>, tag: impl Into<String>) -> Self {
Self {
repository: repository.into(),
tag: tag.into(),
}
}
/// Returns the repository name (e.g. `"torrust/tracker"`)
#[must_use]
pub fn repository(&self) -> &str {
&self.repository
}
/// Returns the image tag (e.g. `"develop"` or `"8.4"`)
#[must_use]
pub fn tag(&self) -> &str {
&self.tag
}
/// Returns the full image reference as `repository:tag`
///
/// # Examples
///
/// ```rust
/// use torrust_tracker_deployer_lib::shared::docker_image::DockerImage;
///
/// let image = DockerImage::new("mysql", "8.4");
/// assert_eq!(image.full_reference(), "mysql:8.4");
/// ```
#[must_use]
pub fn full_reference(&self) -> String {
format!("{}:{}", self.repository, self.tag)
}
}
impl fmt::Display for DockerImage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.repository, self.tag)
}
}
impl From<(&str, &str)> for DockerImage {
fn from((repository, tag): (&str, &str)) -> Self {
Self::new(repository, tag)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_should_create_docker_image_with_repository_and_tag() {
let image = DockerImage::new("torrust/tracker", "develop");
assert_eq!(image.repository(), "torrust/tracker");
assert_eq!(image.tag(), "develop");
}
#[test]
fn it_should_return_full_reference_as_repository_colon_tag() {
let image = DockerImage::new("torrust/tracker", "develop");
assert_eq!(image.full_reference(), "torrust/tracker:develop");
}
#[test]
fn it_should_display_as_full_reference() {
let image = DockerImage::new("mysql", "8.4");
assert_eq!(format!("{image}"), "mysql:8.4");
}
#[test]
fn it_should_create_from_str_tuple() {
let image = DockerImage::from(("prom/prometheus", "v3.5.1"));
assert_eq!(image.full_reference(), "prom/prometheus:v3.5.1");
}
#[test]
fn it_should_implement_equality() {
let a = DockerImage::new("grafana/grafana", "12.4.2");
let b = DockerImage::new("grafana/grafana", "12.4.2");
let c = DockerImage::new("grafana/grafana", "11.4.0");
assert_eq!(a, b);
assert_ne!(a, c);
}
}