Skip to content

Commit 0c655ec

Browse files
committed
feat: add Display for ClusterCondition (#608)
This PR adds a `Display` impl for `ClusterCondition`. It might be worth a thought that we want to provide different `display_*` methods for various levels of verbosity. Co-authored-by: Techassi <sascha.lautenschlaeger@stackable.tech>
1 parent e375b23 commit 0c655ec

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

src/status/condition/mod.rs

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,98 @@ pub struct ClusterCondition {
108108
pub type_: ClusterConditionType,
109109
}
110110

111+
impl std::fmt::Display for ClusterCondition {
112+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113+
let out = match self.type_ {
114+
ClusterConditionType::Available => match self.status {
115+
ClusterConditionStatus::True => "Available",
116+
ClusterConditionStatus::False => "Unavailable",
117+
ClusterConditionStatus::Unknown => "Availability unknown",
118+
},
119+
ClusterConditionType::Degraded => match self.status {
120+
ClusterConditionStatus::True => "Degraded",
121+
ClusterConditionStatus::False => "Not degraded",
122+
ClusterConditionStatus::Unknown => "Degradation unknown",
123+
},
124+
ClusterConditionType::Progressing => match self.status {
125+
ClusterConditionStatus::True => "Progressing",
126+
ClusterConditionStatus::False => "Not progressing",
127+
ClusterConditionStatus::Unknown => "Progression unknown",
128+
},
129+
ClusterConditionType::ReconciliationPaused => match self.status {
130+
ClusterConditionStatus::True => "Reconciling",
131+
ClusterConditionStatus::False => "Not reconciling",
132+
ClusterConditionStatus::Unknown => "Reconciliation unknown",
133+
},
134+
ClusterConditionType::Stopped => match self.status {
135+
ClusterConditionStatus::True => "Stopped",
136+
ClusterConditionStatus::False => "Running",
137+
ClusterConditionStatus::Unknown => "Stopped status unknown",
138+
},
139+
};
140+
141+
out.fmt(f)
142+
}
143+
}
144+
145+
impl ClusterCondition {
146+
/// Returns if the [`ClusterCondition`] is considered to be in a good /
147+
/// healthy state.
148+
pub fn is_good(&self) -> bool {
149+
match self.type_ {
150+
ClusterConditionType::Available => match self.status {
151+
ClusterConditionStatus::False | ClusterConditionStatus::Unknown => false,
152+
ClusterConditionStatus::True => true,
153+
},
154+
ClusterConditionType::Degraded => match self.status {
155+
ClusterConditionStatus::False | ClusterConditionStatus::Unknown => true,
156+
ClusterConditionStatus::True => false,
157+
},
158+
ClusterConditionType::Progressing => match self.status {
159+
ClusterConditionStatus::False | ClusterConditionStatus::Unknown => false,
160+
ClusterConditionStatus::True => true,
161+
},
162+
ClusterConditionType::ReconciliationPaused => match self.status {
163+
ClusterConditionStatus::False | ClusterConditionStatus::True => true,
164+
ClusterConditionStatus::Unknown => false,
165+
},
166+
ClusterConditionType::Stopped => match self.status {
167+
ClusterConditionStatus::True | ClusterConditionStatus::Unknown => false,
168+
ClusterConditionStatus::False => true,
169+
},
170+
}
171+
}
172+
173+
/// Returns a short display string. This method wraps the
174+
/// [`std::fmt::Display`] implementation of the [`ClusterCondition`].
175+
pub fn display_short(&self) -> String {
176+
self.to_string()
177+
}
178+
179+
/// Returns a long display string. This method uses the
180+
/// [`std::fmt::Display`] implementation of the [`ClusterCondition`] and
181+
/// combines it with the optional message to provide more context.
182+
pub fn display_long(&self) -> String {
183+
match &self.message {
184+
Some(message) => format!("{}: {}", self, message),
185+
None => self.to_string(),
186+
}
187+
}
188+
189+
/// Returns either a short or long display string, This method additionally
190+
/// checks if the condition is considered to be in a good state and then
191+
/// returns the short display string. In case the condition is considered
192+
/// to be in an unhealthy state, the method returns a long display string
193+
/// which contains the optional message to provide more context. Internally
194+
/// this method uses the `display_short` and `display_long` methods.
195+
pub fn display_short_or_long(&self) -> String {
196+
match self.is_good() {
197+
true => self.display_short(),
198+
false => self.display_long(),
199+
}
200+
}
201+
}
202+
111203
#[derive(
112204
Clone,
113205
Copy,
@@ -499,4 +591,82 @@ mod test {
499591
assert_eq!(got.status, expected.status);
500592
assert_eq!(got.message, expected.message);
501593
}
594+
595+
#[test]
596+
fn test_display_short() {
597+
let condition = ClusterCondition {
598+
type_: ClusterConditionType::Available,
599+
status: ClusterConditionStatus::False,
600+
message: Some("This should not be displayed".into()),
601+
..Default::default()
602+
};
603+
604+
assert!(!condition.is_good());
605+
assert_eq!(condition.display_short(), "Unavailable".to_string());
606+
607+
let condition = ClusterCondition {
608+
type_: ClusterConditionType::Available,
609+
status: ClusterConditionStatus::True,
610+
message: Some("This should not be displayed".into()),
611+
..Default::default()
612+
};
613+
614+
assert!(condition.is_good());
615+
assert_eq!(condition.display_short(), "Available".to_string());
616+
}
617+
618+
#[test]
619+
fn test_display_long() {
620+
let condition = ClusterCondition {
621+
type_: ClusterConditionType::Available,
622+
status: ClusterConditionStatus::False,
623+
message: Some("This should be displayed".into()),
624+
..Default::default()
625+
};
626+
627+
assert!(!condition.is_good());
628+
assert_eq!(
629+
condition.display_long(),
630+
"Unavailable: This should be displayed".to_string()
631+
);
632+
633+
let condition = ClusterCondition {
634+
type_: ClusterConditionType::Available,
635+
status: ClusterConditionStatus::True,
636+
message: Some("This should be displayed".into()),
637+
..Default::default()
638+
};
639+
640+
assert!(condition.is_good());
641+
assert_eq!(
642+
condition.display_long(),
643+
"Available: This should be displayed".to_string()
644+
);
645+
}
646+
647+
#[test]
648+
fn test_display_short_or_long() {
649+
let condition = ClusterCondition {
650+
type_: ClusterConditionType::Available,
651+
status: ClusterConditionStatus::False,
652+
message: Some("This should be displayed if unhealthy".into()),
653+
..Default::default()
654+
};
655+
656+
assert!(!condition.is_good());
657+
assert_eq!(
658+
condition.display_short_or_long(),
659+
"Unavailable: This should be displayed if unhealthy".to_string()
660+
);
661+
662+
let condition = ClusterCondition {
663+
type_: ClusterConditionType::Available,
664+
status: ClusterConditionStatus::True,
665+
message: Some("This should not be displayed".into()),
666+
..Default::default()
667+
};
668+
669+
assert!(condition.is_good());
670+
assert_eq!(condition.display_short_or_long(), "Available".to_string());
671+
}
502672
}

0 commit comments

Comments
 (0)