Skip to content

Commit 0666a35

Browse files
committed
Add AsRef and Deref for values::Path; additional assertions (#331)
1 parent 3b55f25 commit 0666a35

File tree

2 files changed

+41
-26
lines changed

2 files changed

+41
-26
lines changed

Diff for: git-config/src/values.rs

+40-25
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ quick_error! {
298298
PwdFileQuery {
299299
display("User home info missing")
300300
}
301-
Unsupported {
302-
display("Not available on this platform")
301+
UserInterpolationUnsupported {
302+
display("User interpolation is not available on this platform")
303303
}
304304
}
305305
}
@@ -308,11 +308,25 @@ quick_error! {
308308
///
309309
/// Git represents file paths as byte arrays, modeled here as owned or borrowed byte sequences.
310310
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
311-
#[allow(missing_docs)]
312311
pub struct Path<'a> {
312+
/// The interpolated path
313313
pub value: Cow<'a, [u8]>,
314314
}
315315

316+
impl<'a> std::ops::Deref for Path<'a> {
317+
type Target = [u8];
318+
319+
fn deref(&self) -> &Self::Target {
320+
self.value.as_ref()
321+
}
322+
}
323+
324+
impl<'a> AsRef<[u8]> for Path<'a> {
325+
fn as_ref(&self) -> &[u8] {
326+
self.value.as_ref()
327+
}
328+
}
329+
316330
impl<'a> TryFrom<Cow<'a, [u8]>> for Path<'a> {
317331
type Error = PathError;
318332

@@ -373,7 +387,7 @@ impl Path<'_> {
373387

374388
#[cfg(target_os = "windows")]
375389
fn interpolate_user(_val: Cow<[u8]>, _slash: u8) -> Result<Path, PathError> {
376-
Err(PathError::Unsupported)
390+
Err(PathError::UserInterpolationUnsupported)
377391
}
378392

379393
#[cfg(not(target_os = "windows"))]
@@ -1524,12 +1538,11 @@ mod path {
15241538
#[test]
15251539
fn not_interpolated() {
15261540
let path = &b"/foo/bar"[..];
1527-
let borrowed_path = Cow::Borrowed(path);
1528-
assert_eq!(
1529-
Path::try_from(borrowed_path).unwrap(),
1530-
Path {
1531-
value: Cow::Borrowed(path)
1532-
}
1541+
let actual = Path::try_from(Cow::Borrowed(path)).unwrap();
1542+
assert_eq!(&*actual, path);
1543+
assert!(
1544+
matches!(&actual.value, Cow::Borrowed(_)),
1545+
"it does not unnecessarily copy values"
15331546
);
15341547
}
15351548

@@ -1547,17 +1560,24 @@ mod path {
15471560
let git_install_dir = "/tmp/git";
15481561
let expected = format!("{}/foo/bar", git_install_dir);
15491562
assert_eq!(
1550-
Path::interpolate(val, Some(std::path::Path::new(git_install_dir))).unwrap(),
1551-
Path {
1552-
value: Cow::Borrowed(expected.as_bytes())
1553-
}
1563+
&*Path::interpolate(val, Some(std::path::Path::new(git_install_dir))).unwrap(),
1564+
expected.as_bytes()
1565+
);
1566+
}
1567+
1568+
#[test]
1569+
fn disabled_prefix_interpoldation() {
1570+
let path = &b"./%(prefix)/foo/bar"[..];
1571+
let git_install_dir = "/tmp/git";
1572+
assert_eq!(
1573+
&*Path::interpolate(Cow::Borrowed(path), Some(std::path::Path::new(git_install_dir))).unwrap(),
1574+
path
15541575
);
15551576
}
15561577

15571578
#[test]
15581579
fn tilde_interpolated() {
15591580
let path = &b"~/foo/bar"[..];
1560-
let borrowed_path = Cow::Borrowed(path);
15611581
let home = dirs::home_dir()
15621582
.expect("empty home")
15631583
.to_str()
@@ -1567,10 +1587,8 @@ mod path {
15671587
let home = home.replace("\\", "/");
15681588
let expected = format!("{}/foo/bar", home);
15691589
assert_eq!(
1570-
Path::try_from(borrowed_path).unwrap(),
1571-
Path {
1572-
value: Cow::Borrowed(expected.as_bytes())
1573-
}
1590+
Path::try_from(Cow::Borrowed(path)).unwrap().as_ref(),
1591+
expected.as_bytes()
15741592
);
15751593
}
15761594

@@ -1579,7 +1597,7 @@ mod path {
15791597
fn user_interpolated() {
15801598
assert!(matches!(
15811599
Path::try_from(Cow::Borrowed(&b"~baz/foo/bar"[..])),
1582-
Err(PathError::Unsupported)
1600+
Err(PathError::UserInterpolationUnsupported)
15831601
));
15841602
}
15851603

@@ -1588,14 +1606,11 @@ mod path {
15881606
fn user_interpolated() {
15891607
let user = std::env::var("USER").unwrap();
15901608
let path = format!("~{}/foo/bar", user);
1591-
let borrowed_path = Cow::Borrowed(path.as_bytes());
15921609
let home = std::env::var("HOME").unwrap();
15931610
let expected = format!("{}/foo/bar", home);
15941611
assert_eq!(
1595-
Path::try_from(borrowed_path).unwrap(),
1596-
Path {
1597-
value: Cow::Borrowed(expected.as_bytes())
1598-
}
1612+
&*Path::try_from(Cow::Borrowed(path.as_bytes())).unwrap(),
1613+
expected.as_bytes()
15991614
);
16001615
}
16011616
}

Diff for: git-config/tests/integration_tests/file_integeration_test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn get_value_for_all_provided_values() -> crate::Result {
8383
assert_eq!(
8484
file.value::<git_config::values::Path>("core", None, "location")?,
8585
git_config::values::Path {
86-
value: Cow::Borrowed(format!("{}/tmp", home).as_bytes())
86+
value: Cow::Owned(format!("{}/tmp", home).into_bytes())
8787
}
8888
);
8989

0 commit comments

Comments
 (0)