Skip to content

Commit 01915ed

Browse files
committed
refactor: Simplify List type
This add a Deref impl for the List type, which removed the need to call .inner() to retrieve the IndexMap. Instead IndexMap's methods can now be used by deref'ing. Also, the SpecIter trait now consumes self, which removes two superflous calls to .clone().
1 parent a9bd54d commit 01915ed

File tree

8 files changed

+49
-81
lines changed

8 files changed

+49
-81
lines changed

rust/stackable-cockpit/src/common/list.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::marker::PhantomData;
1+
use std::{marker::PhantomData, ops::Deref};
22

33
use indexmap::IndexMap;
44
use serde::{Deserialize, Serialize};
@@ -18,7 +18,7 @@ pub enum Error {
1818
}
1919

2020
pub trait SpecIter<S> {
21-
fn inner(&self) -> &IndexMap<String, S>;
21+
fn inner(self) -> IndexMap<String, S>;
2222
}
2323

2424
/// A [`List`] describes a list of specs. The list can contain any specs, for
@@ -54,7 +54,7 @@ where
5454
.context(FileTransferSnafu)?;
5555

5656
for (spec_name, spec) in specs.inner() {
57-
map.insert(spec_name.clone(), spec.clone());
57+
map.insert(spec_name, spec);
5858
}
5959
}
6060

@@ -63,17 +63,16 @@ where
6363
inner: map,
6464
})
6565
}
66+
}
6667

67-
/// Returns a reference to the inner [`IndexMap`]
68-
pub fn inner(&self) -> &IndexMap<String, S> {
69-
&self.inner
70-
}
68+
impl<L, S> Deref for List<L, S>
69+
where
70+
L: for<'a> Deserialize<'a> + Serialize + SpecIter<S>,
71+
S: for<'a> Deserialize<'a> + Serialize + Clone,
72+
{
73+
type Target = IndexMap<String, S>;
7174

72-
/// Returns an optional reference to a single spec of type `S` by `name`
73-
pub fn get<T>(&self, name: T) -> Option<&S>
74-
where
75-
T: AsRef<str>,
76-
{
77-
self.inner.get(name.as_ref())
75+
fn deref(&self) -> &Self::Target {
76+
&self.inner
7877
}
7978
}

rust/stackable-cockpit/src/platform/demo/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pub struct DemosV2 {
1818
}
1919

2020
impl SpecIter<DemoSpec> for DemosV2 {
21-
fn inner(&self) -> &IndexMap<String, DemoSpec> {
22-
&self.demos
21+
fn inner(self) -> IndexMap<String, DemoSpec> {
22+
self.demos
2323
}
2424
}
2525

rust/stackable-cockpit/src/platform/release/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,9 @@ pub struct Releases {
1515
}
1616

1717
impl SpecIter<ReleaseSpec> for Releases {
18-
fn inner(&self) -> &IndexMap<String, ReleaseSpec> {
19-
&self.releases
18+
fn inner(self) -> IndexMap<String, ReleaseSpec> {
19+
self.releases
2020
}
2121
}
2222

2323
pub type ReleaseList = crate::common::list::List<Releases, ReleaseSpec>;
24-
25-
#[derive(Default)]
26-
pub struct Release {}

rust/stackable-cockpit/src/platform/release/spec.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use futures::{StreamExt as _, TryStreamExt};
22
use indexmap::IndexMap;
3-
use regex::Regex;
43
use serde::{Deserialize, Serialize};
5-
use snafu::{OptionExt, ResultExt, Snafu};
4+
use snafu::{ResultExt, Snafu};
65
use tokio::task::JoinError;
76
use tracing::{info, instrument};
87

@@ -17,8 +16,6 @@ use crate::{
1716
},
1817
};
1918

20-
use super::ReleaseList;
21-
2219
type Result<T, E = Error> = std::result::Result<T, E>;
2320

2421
#[derive(Debug, Snafu)]
@@ -34,12 +31,6 @@ pub enum Error {
3431

3532
#[snafu(display("failed to launch background task"))]
3633
BackgroundTask { source: JoinError },
37-
38-
#[snafu(display("release list is empty"))]
39-
EmptyReleaseList,
40-
41-
#[snafu(display("latest release doesn't have expected format"))]
42-
LatestReleaseFormat,
4334
}
4435

4536
#[derive(Clone, Debug, Deserialize, Serialize)]
@@ -128,21 +119,3 @@ impl ReleaseSpec {
128119
.collect()
129120
}
130121
}
131-
132-
impl ReleaseList {
133-
/// Checks if a value provided in the '--release' argument is in the release list
134-
pub fn contains(&self, release: &str) -> bool {
135-
self.inner().contains_key(release)
136-
}
137-
138-
/// Retrieves the latest release from the list and applies a sanity check to the release format.
139-
pub fn latest_release(&self) -> Result<String, Error> {
140-
let release = self.inner().first().context(EmptyReleaseListSnafu)?.0;
141-
let sanity_check = Regex::new("^[0-9]{2}.[0-9]{1,2}$").unwrap();
142-
if sanity_check.is_match(release) {
143-
Ok(release.to_string())
144-
} else {
145-
LatestReleaseFormatSnafu {}.fail()
146-
}
147-
}
148-
}

rust/stackable-cockpit/src/platform/stack/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pub struct StacksV2 {
1818
}
1919

2020
impl SpecIter<StackSpec> for StacksV2 {
21-
fn inner(&self) -> &IndexMap<String, StackSpec> {
22-
&self.stacks
21+
fn inner(self) -> IndexMap<String, StackSpec> {
22+
self.stacks
2323
}
2424
}
2525

rust/stackablectl/src/cmds/demo.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ use comfy_table::{
33
presets::{NOTHING, UTF8_FULL},
44
ContentArrangement, Row, Table,
55
};
6-
use snafu::{ResultExt, Snafu};
6+
use snafu::{ensure, OptionExt as _, ResultExt, Snafu};
77
use stackable_operator::kvp::{LabelError, Labels};
88
use tracing::{debug, info, instrument};
99

1010
use stackable_cockpit::{
1111
common::list,
1212
constants::{DEFAULT_OPERATOR_NAMESPACE, DEFAULT_PRODUCT_NAMESPACE},
1313
platform::{
14-
self,
1514
demo::{self, DemoInstallParameters},
1615
release, stack,
1716
},
@@ -131,11 +130,11 @@ pub enum CmdError {
131130
#[snafu(display("no stack with name '{name}'"))]
132131
NoSuchStack { name: String },
133132

134-
#[snafu(display("no release with name '{name}'"))]
135-
NoSuchRelease { name: String },
133+
#[snafu(display("no release '{release}'"))]
134+
NoSuchRelease { release: String },
136135

137136
#[snafu(display("failed to get latest release"))]
138-
LatestRelease { source: platform::release::Error },
137+
LatestRelease,
139138

140139
#[snafu(display("failed to build demo/stack/release list"))]
141140
BuildList { source: list::Error },
@@ -173,20 +172,20 @@ impl DemoArgs {
173172

174173
let release_branch = match &self.release {
175174
Some(release) => {
176-
if !release_list.contains(release) {
177-
return NoSuchReleaseSnafu { name: release }.fail();
178-
}
175+
ensure!(
176+
release_list.contains_key(release),
177+
NoSuchReleaseSnafu { release }
178+
);
179+
179180
if release == "dev" {
180181
"main".to_string()
181182
} else {
182183
format!("release-{release}")
183184
}
184185
}
185186
None => {
186-
format!(
187-
"release-{release}",
188-
release = release_list.latest_release().context(LatestReleaseSnafu)?
189-
)
187+
let (release_name, _) = release_list.first().context(LatestReleaseSnafu)?;
188+
format!("release-{release}", release = release_name,)
190189
}
191190
};
192191

@@ -228,7 +227,7 @@ async fn list_cmd(args: &DemoListArgs, cli: &Cli, list: demo::List) -> Result<St
228227
.set_content_arrangement(arrangement)
229228
.load_preset(preset);
230229

231-
for (index, (demo_name, demo_spec)) in list.inner().iter().enumerate() {
230+
for (index, (demo_name, demo_spec)) in list.iter().enumerate() {
232231
let row = Row::from(vec![
233232
(index + 1).to_string(),
234233
demo_name.clone(),
@@ -253,8 +252,8 @@ async fn list_cmd(args: &DemoListArgs, cli: &Cli, list: demo::List) -> Result<St
253252

254253
Ok(result.render())
255254
}
256-
OutputType::Json => serde_json::to_string(&list.inner()).context(SerializeJsonOutputSnafu),
257-
OutputType::Yaml => serde_yaml::to_string(&list.inner()).context(SerializeYamlOutputSnafu),
255+
OutputType::Json => serde_json::to_string(&*list).context(SerializeJsonOutputSnafu),
256+
OutputType::Yaml => serde_yaml::to_string(&*list).context(SerializeYamlOutputSnafu),
258257
}
259258
}
260259

rust/stackablectl/src/cmds/release.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl ReleaseArgs {
138138
.await
139139
.context(BuildListSnafu)?;
140140

141-
if release_list.inner().is_empty() {
141+
if release_list.is_empty() {
142142
return Ok("No releases".into());
143143
}
144144

@@ -161,7 +161,7 @@ async fn list_cmd(
161161

162162
match args.output_type {
163163
OutputType::Plain | OutputType::Table => {
164-
if release_list.inner().is_empty() {
164+
if release_list.is_empty() {
165165
return Ok("No releases".into());
166166
}
167167

@@ -176,7 +176,7 @@ async fn list_cmd(
176176
.set_content_arrangement(arrangement)
177177
.load_preset(preset);
178178

179-
for (index, (release_name, release_spec)) in release_list.inner().iter().enumerate() {
179+
for (index, (release_name, release_spec)) in release_list.iter().enumerate() {
180180
table.add_row(vec![
181181
(index + 1).to_string(),
182182
release_name.to_string(),

rust/stackablectl/src/cmds/stack.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ use comfy_table::{
33
presets::{NOTHING, UTF8_FULL},
44
ContentArrangement, Table,
55
};
6-
use snafu::{ResultExt, Snafu};
6+
use snafu::{ensure, OptionExt as _, ResultExt, Snafu};
77
use stackable_operator::kvp::{LabelError, Labels};
88
use tracing::{debug, info, instrument};
99

1010
use stackable_cockpit::{
1111
common::list,
1212
constants::{DEFAULT_OPERATOR_NAMESPACE, DEFAULT_PRODUCT_NAMESPACE},
1313
platform::{
14-
self, release,
14+
release,
1515
stack::{self, StackInstallParameters},
1616
},
1717
utils::{
@@ -120,11 +120,11 @@ pub enum CmdError {
120120
#[snafu(display("failed to serialize JSON output"))]
121121
SerializeJsonOutput { source: serde_json::Error },
122122

123-
#[snafu(display("no release with name '{name}'"))]
124-
NoSuchRelease { name: String },
123+
#[snafu(display("no release '{release}'"))]
124+
NoSuchRelease { release: String },
125125

126126
#[snafu(display("failed to get latest release"))]
127-
LatestRelease { source: platform::release::Error },
127+
LatestRelease,
128128

129129
#[snafu(display("failed to build stack/release list"))]
130130
BuildList { source: list::Error },
@@ -158,20 +158,20 @@ impl StackArgs {
158158

159159
let release_branch = match &self.release {
160160
Some(release) => {
161-
if !release_list.contains(release) {
162-
return NoSuchReleaseSnafu { name: release }.fail();
163-
}
161+
ensure!(
162+
release_list.contains_key(release),
163+
NoSuchReleaseSnafu { release }
164+
);
165+
164166
if release == "dev" {
165167
"main".to_string()
166168
} else {
167169
format!("release-{release}")
168170
}
169171
}
170172
None => {
171-
format!(
172-
"release-{release}",
173-
release = release_list.latest_release().context(LatestReleaseSnafu)?
174-
)
173+
let (release_name, _) = release_list.first().context(LatestReleaseSnafu)?;
174+
format!("release-{release}", release = release_name,)
175175
}
176176
};
177177

@@ -213,7 +213,7 @@ fn list_cmd(
213213
.set_content_arrangement(arrangement)
214214
.load_preset(preset);
215215

216-
for (index, (stack_name, stack)) in stack_list.inner().iter().enumerate() {
216+
for (index, (stack_name, stack)) in stack_list.iter().enumerate() {
217217
table.add_row(vec![
218218
(index + 1).to_string(),
219219
stack_name.clone(),

0 commit comments

Comments
 (0)