Skip to content

Commit d40366e

Browse files
committed
Implement try_from for RelativePath
1 parent 13a30b6 commit d40366e

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

gix-path/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
//! ever get into a code-path which does panic though.
4848
//! </details>
4949
#![deny(missing_docs, rust_2018_idioms)]
50-
#![cfg_attr(not(test), forbid(unsafe_code))]
50+
#![cfg_attr(not(test), deny(unsafe_code))]
5151

5252
/// A dummy type to represent path specs and help finding all spots that take path specs once it is implemented.
5353
mod convert;

gix-path/src/relative_path.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::u8;
77

88
use crate::os_str_into_bstr;
99
use crate::try_from_bstr;
10+
use crate::try_from_byte_slice;
1011

1112
/// A wrapper for `BStr`. It is used to enforce the following constraints:
1213
///
@@ -19,6 +20,14 @@ pub struct RelativePath {
1920
}
2021

2122
impl RelativePath {
23+
fn new_unchecked(value: &BStr) -> Result<&RelativePath, Error> {
24+
// SAFETY: `RelativePath` is transparent and equivalent to a `&BStr` if provided as reference.
25+
#[allow(unsafe_code)]
26+
unsafe {
27+
std::mem::transmute(value)
28+
}
29+
}
30+
2231
/// TODO
2332
/// Needs docs.
2433
pub fn ends_with(&self, needle: &[u8]) -> bool {
@@ -49,24 +58,44 @@ impl<'a> TryFrom<&'a BStr> for &'a RelativePath {
4958
gix_validate::path::component(component, None, options)?;
5059
}
5160

52-
todo!()
61+
RelativePath::new_unchecked(value)
5362
}
5463
}
5564

5665
impl<'a, const N: usize> TryFrom<&'a [u8; N]> for &'a RelativePath {
5766
type Error = Error;
5867

5968
#[inline]
60-
fn try_from(_value: &'a [u8; N]) -> Result<Self, Self::Error> {
61-
todo!()
69+
fn try_from(value: &'a [u8; N]) -> Result<Self, Self::Error> {
70+
let path: &std::path::Path = &try_from_byte_slice(value)?;
71+
72+
let options: Options = Default::default();
73+
74+
for component in path.components() {
75+
let component = os_str_into_bstr(component.as_os_str())?;
76+
77+
gix_validate::path::component(component, None, options)?;
78+
}
79+
80+
RelativePath::new_unchecked(value.into())
6281
}
6382
}
6483

65-
impl TryFrom<BString> for &RelativePath {
84+
impl<'a> TryFrom<&'a BString> for &'a RelativePath {
6685
type Error = Error;
6786

68-
fn try_from(_value: BString) -> Result<Self, Self::Error> {
69-
todo!()
87+
fn try_from(value: &'a BString) -> Result<Self, Self::Error> {
88+
let path: &std::path::Path = &try_from_bstr(value.as_bstr())?;
89+
90+
let options: Options = Default::default();
91+
92+
for component in path.components() {
93+
let component = os_str_into_bstr(component.as_os_str())?;
94+
95+
gix_validate::path::component(component, None, options)?;
96+
}
97+
98+
RelativePath::new_unchecked(value.as_bstr())
7099
}
71100
}
72101

0 commit comments

Comments
 (0)