nix_compat/derived_path/
legacy.rs1use std::{fmt, str::FromStr};
2
3use crate::{derived_path::OutputSpec, store_path::StorePath};
4
5use super::DerivedPath;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18#[repr(transparent)]
19pub struct LegacyDerivedPath(DerivedPath);
20impl LegacyDerivedPath {
21 pub fn from_path(path: DerivedPath) -> Self {
22 Self(path)
23 }
24
25 pub fn as_path(&self) -> &DerivedPath {
26 &self.0
27 }
28
29 pub fn into_path(self) -> DerivedPath {
30 self.0
31 }
32}
33
34impl fmt::Display for LegacyDerivedPath {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match &self.0 {
37 DerivedPath::Opaque(store_path) => write!(f, "{}", store_path.to_absolute_path()),
38 DerivedPath::Built { drv_path, outputs } => {
39 write!(f, "{}!{}", drv_path.to_absolute_path(), outputs)
40 }
41 }
42 }
43}
44
45impl FromStr for LegacyDerivedPath {
46 type Err = super::ParseDerivedPathError;
47
48 fn from_str(s: &str) -> Result<Self, Self::Err> {
49 if let Some((prefix, outputs_s)) = s.rsplit_once('!') {
50 let drv_path = StorePath::from_absolute_path(prefix.as_bytes())?;
51 let outputs = outputs_s.parse::<OutputSpec>()?;
52 Ok(LegacyDerivedPath(DerivedPath::Built { drv_path, outputs }))
53 } else {
54 Ok(LegacyDerivedPath(DerivedPath::Opaque(
55 StorePath::from_absolute_path(s.as_bytes())?,
56 )))
57 }
58 }
59}
60
61impl From<DerivedPath> for LegacyDerivedPath {
62 fn from(value: DerivedPath) -> Self {
63 value.into_legacy_format()
64 }
65}
66
67impl<'a> From<&'a DerivedPath> for &'a LegacyDerivedPath {
68 fn from(value: &'a DerivedPath) -> Self {
69 value.as_legacy_format()
70 }
71}
72
73impl From<LegacyDerivedPath> for DerivedPath {
74 fn from(value: LegacyDerivedPath) -> Self {
75 value.into_path()
76 }
77}
78
79impl<'a> From<&'a LegacyDerivedPath> for &'a DerivedPath {
80 fn from(value: &'a LegacyDerivedPath) -> Self {
81 value.as_path()
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use rstest::rstest;
88
89 use super::*;
90 #[rstest]
91 #[case("/nix/store/00000000000000000000000000000000-test.drv", DerivedPath::Opaque("00000000000000000000000000000000-test.drv".parse().unwrap()))]
92 #[case("/nix/store/00000000000000000000000000000000-test.drv!out", DerivedPath::Built {
93 drv_path: "00000000000000000000000000000000-test.drv".parse().unwrap(),
94 outputs: "out".parse().unwrap(),
95 })]
96 #[case("/nix/store/00000000000000000000000000000000-test.drv!*", DerivedPath::Built {
97 drv_path: "00000000000000000000000000000000-test.drv".parse().unwrap(),
98 outputs: "*".parse().unwrap(),
99 })]
100 #[case("/nix/store/00000000000000000000000000000000-test.drv!bin,lib", DerivedPath::Built {
101 drv_path: "00000000000000000000000000000000-test.drv".parse().unwrap(),
102 outputs: "bin,lib".parse().unwrap(),
103 })]
104 fn parse(#[case] input: &str, #[case] expected: DerivedPath) {
105 let actual = input.parse::<LegacyDerivedPath>().unwrap().into_path();
106 assert_eq!(actual, expected);
107 }
108
109 #[rstest]
110 #[case("/nix/store/00000000000000000000000000000000-test.drv!out!bin,lib")]
112 #[case("/nix/store/00000000000000000000000000000000-test.drv!out!bin!lib")]
114 #[case("/nix/store/00000000000000000000000000000000-test.drv^out")]
116 #[case("/nix/store/00000000000000000000000000000000-test.drv^out!bin")]
118 #[case("/nix/store/00000000000000000000000000000000-test.drv!out!bin^out!lib")]
120 #[should_panic(expected = "StorePath(Name)")]
121 fn parse_fail(#[case] input: &str) {
122 input.parse::<LegacyDerivedPath>().unwrap();
123 }
124
125 #[rstest]
126 #[case(DerivedPath::Opaque("00000000000000000000000000000000-test.drv".parse().unwrap()), "/nix/store/00000000000000000000000000000000-test.drv")]
127 #[case(DerivedPath::Built {
128 drv_path: "00000000000000000000000000000000-test.drv".parse().unwrap(),
129 outputs: "out".parse().unwrap(),
130 }, "/nix/store/00000000000000000000000000000000-test.drv!out")]
131 #[case(DerivedPath::Built {
132 drv_path: "00000000000000000000000000000000-test.drv".parse().unwrap(),
133 outputs: "*".parse().unwrap(),
134 }, "/nix/store/00000000000000000000000000000000-test.drv!*")]
135 #[case(DerivedPath::Built {
136 drv_path: "00000000000000000000000000000000-test.drv".parse().unwrap(),
137 outputs: "bin,lib".parse().unwrap(),
138 }, "/nix/store/00000000000000000000000000000000-test.drv!bin,lib")]
139 fn display(#[case] value: DerivedPath, #[case] expected: &str) {
140 assert_eq!(value.as_legacy_format().to_string(), expected);
141 }
142}