flake_edit/app/commands/
uri.rs1use nix_uri::FlakeRef;
2
3use crate::change::{Change, ChangeId};
4
5use super::{Error, Result};
6
7#[derive(Default)]
15pub struct UriOptions<'a> {
16 pub ref_or_rev: Option<&'a str>,
17 pub shallow: bool,
18}
19
20pub(super) enum BuildKind {
22 Add { no_flake: bool },
23 Change,
24}
25
26pub(super) fn build_uri_change(
29 kind: BuildKind,
30 id: String,
31 uri: String,
32 opts: &UriOptions<'_>,
33) -> Result<Change> {
34 let final_uri = transform_uri(uri, opts.ref_or_rev, opts.shallow)?;
35 let id = ChangeId::parse(&id).map_err(|source| Error::InvalidInputId { id, source })?;
36 Ok(match kind {
37 BuildKind::Add { no_flake } => Change::Add {
38 id: Some(id),
39 uri: Some(final_uri),
40 flake: !no_flake,
41 },
42 BuildKind::Change => Change::Change {
43 id: Some(id),
44 uri: Some(final_uri),
45 },
46 })
47}
48
49pub(super) fn apply_uri_options(
53 flake_ref: FlakeRef,
54 ref_or_rev: Option<&str>,
55 shallow: bool,
56) -> FlakeRef {
57 let mut flake_ref = if let Some(ror) = ref_or_rev {
58 flake_ref.with_ref(Some(ror.to_string()))
59 } else {
60 flake_ref
61 };
62 if shallow {
63 flake_ref.set_shallow(true);
64 }
65 flake_ref
66}
67
68pub(super) fn transform_uri(
76 uri: String,
77 ref_or_rev: Option<&str>,
78 shallow: bool,
79) -> Result<String> {
80 let flake_ref: FlakeRef = uri.parse().map_err(|source| Error::InvalidUri {
81 uri: uri.clone(),
82 source,
83 })?;
84
85 if ref_or_rev.is_none() && !shallow {
86 return Ok(uri);
87 }
88
89 Ok(apply_uri_options(flake_ref, ref_or_rev, shallow).into_uri())
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn malformed_id_surfaces_as_invalid_input_id() {
98 let opts = UriOptions::default();
99 let err = build_uri_change(
100 BuildKind::Change,
101 "a..b".to_string(),
102 "github:owner/repo".to_string(),
103 &opts,
104 )
105 .expect_err("a malformed id must not build a Change");
106 assert!(
107 matches!(&err, Error::InvalidInputId { id, .. } if id == "a..b"),
108 "expected InvalidInputId for 'a..b', got: {err:?}"
109 );
110 }
111}