Skip to content

Commit 4f7e80c

Browse files
committed
Refactor implement from_str trait for Target data
1 parent 71e7c40 commit 4f7e80c

File tree

2 files changed

+101
-98
lines changed

2 files changed

+101
-98
lines changed

src/cli.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ pub enum GetDeploymentDataError {
171171
/// Evaluates the Nix in the given `repo` and return the processed Data from it
172172
async fn get_deployment_data(
173173
supports_flakes: bool,
174-
flakes: &[data::DeployFlake<'_>],
174+
flakes: &[data::Target],
175175
extra_build_args: &[String],
176176
) -> Result<Vec<settings::Root>, GetDeploymentDataError> {
177177
futures_util::stream::iter(flakes).then(|flake| async move {
@@ -275,7 +275,7 @@ struct PromptPart<'a> {
275275

276276
fn print_deployment(
277277
parts: &[(
278-
&data::DeployFlake<'_>,
278+
&data::Target,
279279
data::DeployData,
280280
data::DeployDefs,
281281
)],
@@ -318,7 +318,7 @@ pub enum PromptDeploymentError {
318318

319319
fn prompt_deployment(
320320
parts: &[(
321-
&data::DeployFlake<'_>,
321+
&data::Target,
322322
data::DeployData,
323323
data::DeployDefs,
324324
)],
@@ -391,14 +391,14 @@ pub enum RunDeployError {
391391
}
392392

393393
type ToDeploy<'a> = Vec<(
394-
&'a data::DeployFlake<'a>,
394+
&'a data::Target,
395395
&'a settings::Root,
396396
(&'a str, &'a settings::Node),
397397
(&'a str, &'a settings::Profile),
398398
)>;
399399

400400
async fn run_deploy(
401-
deploy_flakes: Vec<data::DeployFlake<'_>>,
401+
deploy_targets: Vec<data::Target>,
402402
data: Vec<settings::Root>,
403403
supports_flakes: bool,
404404
check_sigs: bool,
@@ -412,11 +412,11 @@ async fn run_deploy(
412412
log_dir: &Option<String>,
413413
rollback_succeeded: bool,
414414
) -> Result<(), RunDeployError> {
415-
let to_deploy: ToDeploy = deploy_flakes
415+
let to_deploy: ToDeploy = deploy_targets
416416
.iter()
417417
.zip(&data)
418-
.map(|(deploy_flake, data)| {
419-
let to_deploys: ToDeploy = match (&deploy_flake.node, &deploy_flake.profile) {
418+
.map(|(deploy_target, data)| {
419+
let to_deploys: ToDeploy = match (&deploy_target.node, &deploy_target.profile) {
420420
(Some(node_name), Some(profile_name)) => {
421421
let node = match data.nodes.get(node_name) {
422422
Some(x) => x,
@@ -428,7 +428,7 @@ async fn run_deploy(
428428
};
429429

430430
vec![(
431-
&deploy_flake,
431+
&deploy_target,
432432
&data,
433433
(node_name.as_str(), node),
434434
(profile_name.as_str(), profile),
@@ -464,7 +464,7 @@ async fn run_deploy(
464464

465465
profiles_list
466466
.into_iter()
467-
.map(|x| (deploy_flake, data, (node_name.as_str(), node), x))
467+
.map(|x| (deploy_target, data, (node_name.as_str(), node), x))
468468
.collect()
469469
}
470470
(None, None) => {
@@ -495,7 +495,7 @@ async fn run_deploy(
495495

496496
let ll: ToDeploy = profiles_list
497497
.into_iter()
498-
.map(|x| (deploy_flake, data, (node_name.as_str(), node), x))
498+
.map(|x| (deploy_target, data, (node_name.as_str(), node), x))
499499
.collect();
500500

501501
l.extend(ll);
@@ -513,12 +513,12 @@ async fn run_deploy(
513513
.collect();
514514

515515
let mut parts: Vec<(
516-
&data::DeployFlake<'_>,
516+
&data::Target,
517517
data::DeployData,
518518
data::DeployDefs,
519519
)> = Vec::new();
520520

521-
for (deploy_flake, data, (node_name, node), (profile_name, profile)) in to_deploy {
521+
for (deploy_target, data, (node_name, node), (profile_name, profile)) in to_deploy {
522522
let deploy_data = data::make_deploy_data(
523523
&data.generic_settings,
524524
node,
@@ -532,7 +532,7 @@ async fn run_deploy(
532532

533533
let deploy_defs = deploy_data.defs()?;
534534

535-
parts.push((deploy_flake, deploy_data, deploy_defs));
535+
parts.push((deploy_target, deploy_data, deploy_defs));
536536
}
537537

538538
if interactive {
@@ -541,11 +541,11 @@ async fn run_deploy(
541541
print_deployment(&parts[..])?;
542542
}
543543

544-
for (deploy_flake, deploy_data, deploy_defs) in &parts {
544+
for (deploy_target, deploy_data, deploy_defs) in &parts {
545545
deploy::push::push_profile(deploy::push::PushProfileData {
546546
supports_flakes,
547547
check_sigs,
548-
repo: deploy_flake.repo,
548+
repo: &deploy_target.repo,
549549
deploy_data: &deploy_data,
550550
deploy_defs: &deploy_defs,
551551
keep_result,
@@ -600,7 +600,7 @@ pub enum RunError {
600600
#[error("Failed to evaluate deployment data: {0}")]
601601
GetDeploymentData(#[from] GetDeploymentDataError),
602602
#[error("Error parsing flake: {0}")]
603-
ParseFlake(#[from] data::ParseFlakeError),
603+
ParseFlake(#[from] data::ParseTargetError),
604604
#[error("Error initiating logger: {0}")]
605605
Logger(#[from] flexi_logger::FlexiLoggerError),
606606
#[error("{0}")]
@@ -624,10 +624,10 @@ pub async fn run(args: Option<&ArgMatches>) -> Result<(), RunError> {
624624
.targets
625625
.unwrap_or_else(|| vec![opts.clone().target.unwrap_or(".".to_string())]);
626626

627-
let deploy_flakes: Vec<data::DeployFlake> = deploys
628-
.iter()
629-
.map(|f| data::parse_flake(f.as_str()))
630-
.collect::<Result<Vec<data::DeployFlake>, data::ParseFlakeError>>()?;
627+
let deploy_targets: Vec<data::Target> = deploys
628+
.into_iter()
629+
.map(|f| f.parse::<data::Target>())
630+
.collect::<Result<Vec<data::Target>, data::ParseTargetError>>()?;
631631

632632
let cmd_overrides = data::CmdOverrides {
633633
ssh_user: opts.ssh_user,
@@ -649,14 +649,14 @@ pub async fn run(args: Option<&ArgMatches>) -> Result<(), RunError> {
649649
}
650650

651651
if !opts.skip_checks {
652-
for deploy_flake in deploy_flakes.iter() {
653-
check_deployment(supports_flakes, deploy_flake.repo, &opts.extra_build_args).await?;
652+
for deploy_target in deploy_targets.iter() {
653+
check_deployment(supports_flakes, &deploy_target.repo, &opts.extra_build_args).await?;
654654
}
655655
}
656656
let result_path = opts.result_path.as_deref();
657-
let data = get_deployment_data(supports_flakes, &deploy_flakes, &opts.extra_build_args).await?;
657+
let data = get_deployment_data(supports_flakes, &deploy_targets, &opts.extra_build_args).await?;
658658
run_deploy(
659-
deploy_flakes,
659+
deploy_targets,
660660
data,
661661
supports_flakes,
662662
opts.checksigs,

src/data.rs

Lines changed: 76 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -10,144 +10,147 @@ use thiserror::Error;
1010
use crate::settings;
1111

1212
#[derive(PartialEq, Debug)]
13-
pub struct DeployFlake<'a> {
14-
pub repo: &'a str,
13+
pub struct Target {
14+
pub repo: String,
1515
pub node: Option<String>,
1616
pub profile: Option<String>,
1717
}
1818

1919
#[derive(Error, Debug)]
20-
pub enum ParseFlakeError {
20+
pub enum ParseTargetError {
2121
#[error("The given path was too long, did you mean to put something in quotes?")]
2222
PathTooLong,
2323
#[error("Unrecognized node or token encountered")]
2424
Unrecognized,
2525
}
26-
27-
pub fn parse_flake(flake: &str) -> Result<DeployFlake, ParseFlakeError> {
28-
let flake_fragment_start = flake.find('#');
29-
let (repo, maybe_fragment) = match flake_fragment_start {
30-
Some(s) => (&flake[..s], Some(&flake[s + 1..])),
31-
None => (flake, None),
32-
};
33-
34-
let mut node: Option<String> = None;
35-
let mut profile: Option<String> = None;
36-
37-
if let Some(fragment) = maybe_fragment {
38-
let ast = rnix::parse(fragment);
39-
40-
let first_child = match ast.root().node().first_child() {
41-
Some(x) => x,
42-
None => {
43-
return Ok(DeployFlake {
44-
repo,
45-
node: None,
46-
profile: None,
47-
})
48-
}
26+
impl std::str::FromStr for Target {
27+
type Err = ParseTargetError;
28+
29+
fn from_str(s: &str) -> Result<Self, Self::Err> {
30+
let flake_fragment_start = s.find('#');
31+
let (repo, maybe_fragment) = match flake_fragment_start {
32+
Some(i) => (s[..i].to_string(), Some(&s[i + 1..])),
33+
None => (s.to_string(), None),
4934
};
5035

51-
let mut node_over = false;
36+
let mut node: Option<String> = None;
37+
let mut profile: Option<String> = None;
5238

53-
for entry in first_child.children_with_tokens() {
54-
let x: Option<String> = match (entry.kind(), node_over) {
55-
(TOKEN_DOT, false) => {
56-
node_over = true;
57-
None
58-
}
59-
(TOKEN_DOT, true) => {
60-
return Err(ParseFlakeError::PathTooLong);
61-
}
62-
(NODE_IDENT, _) => Some(entry.into_node().unwrap().text().to_string()),
63-
(TOKEN_IDENT, _) => Some(entry.into_token().unwrap().text().to_string()),
64-
(NODE_STRING, _) => {
65-
let c = entry
66-
.into_node()
67-
.unwrap()
68-
.children_with_tokens()
69-
.nth(1)
70-
.unwrap();
71-
72-
Some(c.into_token().unwrap().text().to_string())
39+
if let Some(fragment) = maybe_fragment {
40+
let ast = rnix::parse(fragment);
41+
42+
let first_child = match ast.root().node().first_child() {
43+
Some(x) => x,
44+
None => {
45+
return Ok(Target {
46+
repo,
47+
node: None,
48+
profile: None,
49+
})
7350
}
74-
_ => return Err(ParseFlakeError::Unrecognized),
7551
};
7652

77-
if !node_over {
78-
node = x;
79-
} else {
80-
profile = x;
53+
let mut node_over = false;
54+
55+
for entry in first_child.children_with_tokens() {
56+
let x: Option<String> = match (entry.kind(), node_over) {
57+
(TOKEN_DOT, false) => {
58+
node_over = true;
59+
None
60+
}
61+
(TOKEN_DOT, true) => {
62+
return Err(ParseTargetError::PathTooLong);
63+
}
64+
(NODE_IDENT, _) => Some(entry.into_node().unwrap().text().to_string()),
65+
(TOKEN_IDENT, _) => Some(entry.into_token().unwrap().text().to_string()),
66+
(NODE_STRING, _) => {
67+
let c = entry
68+
.into_node()
69+
.unwrap()
70+
.children_with_tokens()
71+
.nth(1)
72+
.unwrap();
73+
74+
Some(c.into_token().unwrap().text().to_string())
75+
}
76+
_ => return Err(ParseTargetError::Unrecognized),
77+
};
78+
79+
if !node_over {
80+
node = x;
81+
} else {
82+
profile = x;
83+
}
8184
}
8285
}
83-
}
8486

85-
Ok(DeployFlake {
86-
repo,
87-
node,
88-
profile,
89-
})
87+
Ok(Target {
88+
repo,
89+
node,
90+
profile,
91+
})
92+
}
9093
}
9194

9295
#[test]
93-
fn test_parse_flake() {
96+
fn test_deploy_target_from_str() {
9497
assert_eq!(
95-
parse_flake("../deploy/examples/system").unwrap(),
96-
DeployFlake {
98+
"../deploy/examples/system".parse::<Target>().unwrap(),
99+
Target {
97100
repo: "../deploy/examples/system",
98101
node: None,
99102
profile: None,
100103
}
101104
);
102105

103106
assert_eq!(
104-
parse_flake("../deploy/examples/system#").unwrap(),
105-
DeployFlake {
107+
"../deploy/examples/system#".parse::<Target>().unwrap(),
108+
Target {
106109
repo: "../deploy/examples/system",
107110
node: None,
108111
profile: None,
109112
}
110113
);
111114

112115
assert_eq!(
113-
parse_flake("../deploy/examples/system#computer.\"something.nix\"").unwrap(),
114-
DeployFlake {
116+
"../deploy/examples/system#computer.\"something.nix\"".parse::<Target>().unwrap(),
117+
Target {
115118
repo: "../deploy/examples/system",
116119
node: Some("computer".to_string()),
117120
profile: Some("something.nix".to_string()),
118121
}
119122
);
120123

121124
assert_eq!(
122-
parse_flake("../deploy/examples/system#\"example.com\".system").unwrap(),
123-
DeployFlake {
125+
"../deploy/examples/system#\"example.com\".system".parse::<Target>().unwrap(),
126+
Target {
124127
repo: "../deploy/examples/system",
125128
node: Some("example.com".to_string()),
126129
profile: Some("system".to_string()),
127130
}
128131
);
129132

130133
assert_eq!(
131-
parse_flake("../deploy/examples/system#example").unwrap(),
132-
DeployFlake {
134+
"../deploy/examples/system#example".parse::<Target>().unwrap(),
135+
Target {
133136
repo: "../deploy/examples/system",
134137
node: Some("example".to_string()),
135138
profile: None
136139
}
137140
);
138141

139142
assert_eq!(
140-
parse_flake("../deploy/examples/system#example.system").unwrap(),
141-
DeployFlake {
143+
"../deploy/examples/system#example.system".parse::<Target>().unwrap(),
144+
Target {
142145
repo: "../deploy/examples/system",
143146
node: Some("example".to_string()),
144147
profile: Some("system".to_string())
145148
}
146149
);
147150

148151
assert_eq!(
149-
parse_flake("../deploy/examples/system").unwrap(),
150-
DeployFlake {
152+
"../deploy/examples/system".parse::<Target>().unwrap(),
153+
Target {
151154
repo: "../deploy/examples/system",
152155
node: None,
153156
profile: None,

0 commit comments

Comments
 (0)