1#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum MarkerDeleteSelector {
7 Name(String),
9 Prefix(String),
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum MarkerDeleteSelectorError {
16 Conflict,
18 Required,
20}
21
22impl MarkerDeleteSelectorError {
23 pub fn kind(self) -> &'static str {
24 match self {
25 Self::Conflict => "marker_delete_selector_conflict",
26 Self::Required => "marker_delete_selector_required",
27 }
28 }
29}
30
31pub fn plan_marker_delete_selector(
33 name: Option<String>,
34 prefix: Option<String>,
35) -> Result<MarkerDeleteSelector, MarkerDeleteSelectorError> {
36 match (name, prefix) {
37 (Some(name), None) => Ok(MarkerDeleteSelector::Name(name)),
38 (None, Some(prefix)) => {
39 if prefix.is_empty() {
40 Ok(MarkerDeleteSelector::Prefix(prefix))
45 } else {
46 Ok(MarkerDeleteSelector::Prefix(prefix))
47 }
48 }
49 (Some(_), Some(_)) => Err(MarkerDeleteSelectorError::Conflict),
50 (None, None) => Err(MarkerDeleteSelectorError::Required),
51 }
52}
53
54pub fn marker_prefix_is_valid(prefix: &str) -> bool {
56 !prefix.is_empty()
57}
58
59pub fn marker_list_filter_matches(name: &str, filter: Option<&str>) -> bool {
61 match filter {
62 Some(prefix) if !prefix.is_empty() => name.starts_with(prefix),
63 _ => true,
64 }
65}
66
67pub fn marker_bulk_delete_message(prefix: &str, count: usize) -> String {
69 match count {
70 0 => format!("No markers matched prefix '{prefix}'"),
71 1 => format!("Deleted 1 marker matching prefix '{prefix}'"),
72 n => format!("Deleted {n} markers matching prefix '{prefix}'"),
73 }
74}
75
76pub fn marker_create_message(name: &str, state_id_short: &str) -> String {
78 format!("Created marker '{name}' at {state_id_short}")
79}
80
81pub fn marker_delete_message(name: &str) -> String {
82 format!("Deleted marker '{name}'")
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn delete_selector_plans() {
91 assert_eq!(
92 plan_marker_delete_selector(Some("m".into()), None).unwrap(),
93 MarkerDeleteSelector::Name("m".into())
94 );
95 assert_eq!(
96 plan_marker_delete_selector(None, Some("pre".into())).unwrap(),
97 MarkerDeleteSelector::Prefix("pre".into())
98 );
99 assert_eq!(
100 plan_marker_delete_selector(Some("a".into()), Some("b".into())),
101 Err(MarkerDeleteSelectorError::Conflict)
102 );
103 assert_eq!(
104 plan_marker_delete_selector(None, None),
105 Err(MarkerDeleteSelectorError::Required)
106 );
107 }
108
109 #[test]
110 fn prefix_and_filter() {
111 assert!(marker_prefix_is_valid("x"));
112 assert!(!marker_prefix_is_valid(""));
113 assert!(marker_list_filter_matches("foo", None));
114 assert!(marker_list_filter_matches("foo", Some("")));
115 assert!(marker_list_filter_matches("foobar", Some("foo")));
116 assert!(!marker_list_filter_matches("bar", Some("foo")));
117 }
118
119 #[test]
120 fn bulk_messages() {
121 assert!(marker_bulk_delete_message("p", 0).contains("No markers"));
122 assert!(marker_bulk_delete_message("p", 1).contains("1 marker"));
123 assert!(marker_bulk_delete_message("p", 3).contains("3 markers"));
124 }
125}