Skip to content

Commit a10cc65

Browse files
committed
Refactor implement from_str trait for Target data
1 parent c99adbd commit a10cc65

File tree

2 files changed

+107
-104
lines changed

2 files changed

+107
-104
lines changed

src/cli.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub enum GetDeploymentDataError {
168168
/// Evaluates the Nix in the given `repo` and return the processed Data from it
169169
async fn get_deployment_data(
170170
supports_flakes: bool,
171-
flakes: &[data::DeployFlake<'_>],
171+
flakes: &[data::Target],
172172
extra_build_args: &[String],
173173
) -> Result<Vec<settings::Root>, GetDeploymentDataError> {
174174
futures_util::stream::iter(flakes).then(|flake| async move {
@@ -272,7 +272,7 @@ struct PromptPart<'a> {
272272

273273
fn print_deployment(
274274
parts: &[(
275-
&data::DeployFlake<'_>,
275+
&data::Target,
276276
data::DeployData,
277277
data::DeployDefs,
278278
)],
@@ -315,7 +315,7 @@ pub enum PromptDeploymentError {
315315

316316
fn prompt_deployment(
317317
parts: &[(
318-
&data::DeployFlake<'_>,
318+
&data::Target,
319319
data::DeployData,
320320
data::DeployDefs,
321321
)],
@@ -388,14 +388,14 @@ pub enum RunDeployError {
388388
}
389389

390390
type ToDeploy<'a> = Vec<(
391-
&'a data::DeployFlake<'a>,
391+
&'a data::Target,
392392
&'a settings::Root,
393393
(&'a str, &'a settings::Node),
394394
(&'a str, &'a settings::Profile),
395395
)>;
396396

397397
async fn run_deploy(
398-
deploy_flakes: Vec<data::DeployFlake<'_>>,
398+
deploy_targets: Vec<data::Target>,
399399
data: Vec<settings::Root>,
400400
supports_flakes: bool,
401401
check_sigs: bool,
@@ -409,11 +409,11 @@ async fn run_deploy(
409409
log_dir: &Option<String>,
410410
rollback_succeeded: bool,
411411
) -> Result<(), RunDeployError> {
412-
let to_deploy: ToDeploy = deploy_flakes
412+
let to_deploy: ToDeploy = deploy_targets
413413
.iter()
414414
.zip(&data)
415-
.map(|(deploy_flake, data)| {
416-
let to_deploys: ToDeploy = match (&deploy_flake.node, &deploy_flake.profile) {
415+
.map(|(deploy_target, data)| {
416+
let to_deploys: ToDeploy = match (&deploy_target.node, &deploy_target.profile) {
417417
(Some(node_name), Some(profile_name)) => {
418418
let node = match data.nodes.get(node_name) {
419419
Some(x) => x,
@@ -425,7 +425,7 @@ async fn run_deploy(
425425
};
426426

427427
vec![(
428-
deploy_flake,
428+
deploy_target,
429429
data,
430430
(node_name.as_str(), node),
431431
(profile_name.as_str(), profile),
@@ -459,7 +459,7 @@ async fn run_deploy(
459459

460460
profiles_list
461461
.into_iter()
462-
.map(|x| (deploy_flake, data, (node_name.as_str(), node), x))
462+
.map(|x| (deploy_target, data, (node_name.as_str(), node), x))
463463
.collect()
464464
}
465465
(None, None) => {
@@ -490,7 +490,7 @@ async fn run_deploy(
490490

491491
let ll: ToDeploy = profiles_list
492492
.into_iter()
493-
.map(|x| (deploy_flake, data, (node_name.as_str(), node), x))
493+
.map(|x| (deploy_target, data, (node_name.as_str(), node), x))
494494
.collect();
495495

496496
l.extend(ll);
@@ -508,12 +508,12 @@ async fn run_deploy(
508508
.collect();
509509

510510
let mut parts: Vec<(
511-
&data::DeployFlake<'_>,
511+
&data::Target,
512512
data::DeployData,
513513
data::DeployDefs,
514514
)> = Vec::new();
515515

516-
for (deploy_flake, data, (node_name, node), (profile_name, profile)) in to_deploy {
516+
for (deploy_target, data, (node_name, node), (profile_name, profile)) in to_deploy {
517517
let deploy_data = data::make_deploy_data(
518518
&data.generic_settings,
519519
node,
@@ -527,7 +527,7 @@ async fn run_deploy(
527527

528528
let deploy_defs = deploy_data.defs()?;
529529

530-
parts.push((deploy_flake, deploy_data, deploy_defs));
530+
parts.push((deploy_target, deploy_data, deploy_defs));
531531
}
532532

533533
if interactive {
@@ -536,11 +536,11 @@ async fn run_deploy(
536536
print_deployment(&parts[..])?;
537537
}
538538

539-
for (deploy_flake, deploy_data, deploy_defs) in &parts {
539+
for (deploy_target, deploy_data, deploy_defs) in &parts {
540540
deploy::push::push_profile(deploy::push::PushProfileData {
541541
supports_flakes,
542542
check_sigs,
543-
repo: deploy_flake.repo,
543+
repo: &deploy_target.repo,
544544
deploy_data,
545545
deploy_defs,
546546
keep_result,
@@ -595,7 +595,7 @@ pub enum RunError {
595595
#[error("Failed to evaluate deployment data: {0}")]
596596
GetDeploymentData(#[from] GetDeploymentDataError),
597597
#[error("Error parsing flake: {0}")]
598-
ParseFlake(#[from] data::ParseFlakeError),
598+
ParseFlake(#[from] data::ParseTargetError),
599599
#[error("Error initiating logger: {0}")]
600600
Logger(#[from] flexi_logger::FlexiLoggerError),
601601
#[error("{0}")]
@@ -619,10 +619,10 @@ pub async fn run(args: Option<&ArgMatches>) -> Result<(), RunError> {
619619
.targets
620620
.unwrap_or_else(|| vec![opts.clone().target.unwrap_or_else(|| ".".to_string())]);
621621

622-
let deploy_flakes: Vec<data::DeployFlake> = deploys
622+
let deploy_targets: Vec<data::Target> = deploys
623623
.iter()
624-
.map(|f| data::parse_flake(f.as_str()))
625-
.collect::<Result<Vec<data::DeployFlake>, data::ParseFlakeError>>()?;
624+
.map(|f| f.parse::<data::Target>())
625+
.collect::<Result<Vec<data::Target>, data::ParseTargetError>>()?;
626626

627627
let cmd_overrides = data::CmdOverrides {
628628
ssh_user: opts.ssh_user,
@@ -644,14 +644,14 @@ pub async fn run(args: Option<&ArgMatches>) -> Result<(), RunError> {
644644
}
645645

646646
if !opts.skip_checks {
647-
for deploy_flake in &deploy_flakes {
648-
check_deployment(supports_flakes, deploy_flake.repo, &opts.extra_build_args).await?;
647+
for deploy_target in deploy_targets.iter() {
648+
check_deployment(supports_flakes, &deploy_target.repo, &opts.extra_build_args).await?;
649649
}
650650
}
651651
let result_path = opts.result_path.as_deref();
652-
let data = get_deployment_data(supports_flakes, &deploy_flakes, &opts.extra_build_args).await?;
652+
let data = get_deployment_data(supports_flakes, &deploy_targets, &opts.extra_build_args).await?;
653653
run_deploy(
654-
deploy_flakes,
654+
deploy_targets,
655655
data,
656656
supports_flakes,
657657
opts.checksigs,

src/data.rs

+83-80
Original file line numberDiff line numberDiff line change
@@ -10,145 +10,148 @@ 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 {
97-
repo: "../deploy/examples/system",
98+
"../deploy/examples/system".parse::<Target>().unwrap(),
99+
Target {
100+
repo: "../deploy/examples/system".to_string(),
98101
node: None,
99102
profile: None,
100103
}
101104
);
102105

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

112115
assert_eq!(
113-
parse_flake("../deploy/examples/system#computer.\"something.nix\"").unwrap(),
114-
DeployFlake {
115-
repo: "../deploy/examples/system",
116+
"../deploy/examples/system#computer.\"something.nix\"".parse::<Target>().unwrap(),
117+
Target {
118+
repo: "../deploy/examples/system".to_string(),
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 {
124-
repo: "../deploy/examples/system",
125+
"../deploy/examples/system#\"example.com\".system".parse::<Target>().unwrap(),
126+
Target {
127+
repo: "../deploy/examples/system".to_string(),
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 {
133-
repo: "../deploy/examples/system",
134+
"../deploy/examples/system#example".parse::<Target>().unwrap(),
135+
Target {
136+
repo: "../deploy/examples/system".to_string(),
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 {
142-
repo: "../deploy/examples/system",
143+
"../deploy/examples/system#example.system".parse::<Target>().unwrap(),
144+
Target {
145+
repo: "../deploy/examples/system".to_string(),
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 {
151-
repo: "../deploy/examples/system",
152+
"../deploy/examples/system".parse::<Target>().unwrap(),
153+
Target {
154+
repo: "../deploy/examples/system".to_string(),
152155
node: None,
153156
profile: None,
154157
}

0 commit comments

Comments
 (0)