Skip to content

Commit b7aab9e

Browse files
committed
feat: Allow PartialNameRef to be created from owned items (#251)
1 parent 06893cf commit b7aab9e

File tree

6 files changed

+45
-14
lines changed

6 files changed

+45
-14
lines changed

git-ref/src/fullname.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl<'a> From<crate::FullNameRef<'a>> for FullName {
5959
impl FullName {
6060
/// Interpret this fully qualified reference name as partial name.
6161
pub fn to_partial(&self) -> crate::PartialNameRef<'_> {
62-
crate::PartialNameRef(self.0.as_bstr())
62+
crate::PartialNameRef(self.0.as_bstr().into())
6363
}
6464

6565
/// Interpret this fully qualified reference as shared full name

git-ref/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
//! * supersedes all of the above to allow handling hundreds of thousands of references.
1919
#![forbid(unsafe_code)]
2020
#![deny(missing_docs, rust_2018_idioms)]
21+
2122
use git_hash::{oid, ObjectId};
2223
pub use git_object::bstr;
2324
use git_object::bstr::{BStr, BString};
25+
use std::borrow::Cow;
2426

2527
mod store;
2628
pub use store::{file, packed};
@@ -55,8 +57,8 @@ pub struct FullName(pub(crate) BString);
5557
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
5658
pub struct FullNameRef<'a>(&'a BStr);
5759
/// A validated complete and fully qualified reference name, safe to use for all operations.
58-
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
59-
pub struct PartialNameRef<'a>(&'a BStr);
60+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
61+
pub struct PartialNameRef<'a>(Cow<'a, BStr>);
6062

6163
/// A _validated_ prefix for references to act as a namespace.
6264
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]

git-ref/src/name.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
path::Path,
55
};
66

7-
use git_object::bstr::{BStr, ByteSlice};
7+
use git_object::bstr::{BStr, BString, ByteSlice};
88

99
use crate::{FullNameRef, PartialNameRef};
1010

@@ -26,13 +26,13 @@ impl<'a> FullNameRef<'a> {
2626
impl<'a> PartialNameRef<'a> {
2727
/// Convert this name into the relative path possibly identifying the reference location.
2828
/// Note that it may be only a partial path though.
29-
pub fn to_partial_path(self) -> Cow<'a, Path> {
29+
pub fn to_partial_path(&'a self) -> Cow<'a, Path> {
3030
self.0.to_path().expect("UTF-8 conversion always succeeds").into()
3131
}
3232

3333
/// Provide the name as binary string which is known to be a valid partial ref name.
34-
pub fn as_bstr(&self) -> &'a BStr {
35-
self.0
34+
pub fn as_bstr(&'a self) -> &'a BStr {
35+
self.0.as_ref()
3636
}
3737
}
3838

@@ -48,15 +48,15 @@ impl<'a> TryFrom<FullNameRef<'a>> for PartialNameRef<'a> {
4848
type Error = Infallible;
4949

5050
fn try_from(v: FullNameRef<'a>) -> Result<Self, Self::Error> {
51-
Ok(PartialNameRef(v.0))
51+
Ok(PartialNameRef(v.0.into()))
5252
}
5353
}
5454

5555
impl<'a> TryFrom<&'a BStr> for PartialNameRef<'a> {
5656
type Error = Error;
5757

5858
fn try_from(v: &'a BStr) -> Result<Self, Self::Error> {
59-
Ok(PartialNameRef(git_validate::reference::name_partial(v)?))
59+
Ok(PartialNameRef(git_validate::reference::name_partial(v)?.into()))
6060
}
6161
}
6262

@@ -74,7 +74,7 @@ impl<'a> TryFrom<&'a str> for PartialNameRef<'a> {
7474

7575
fn try_from(v: &'a str) -> Result<Self, Self::Error> {
7676
let v = v.as_bytes().as_bstr();
77-
Ok(PartialNameRef(git_validate::reference::name_partial(v)?))
77+
Ok(PartialNameRef(git_validate::reference::name_partial(v)?.into()))
7878
}
7979
}
8080

@@ -92,6 +92,24 @@ impl<'a> TryFrom<&'a String> for PartialNameRef<'a> {
9292

9393
fn try_from(v: &'a String) -> Result<Self, Self::Error> {
9494
let v = v.as_bytes().as_bstr();
95-
Ok(PartialNameRef(git_validate::reference::name_partial(v)?))
95+
Ok(PartialNameRef(git_validate::reference::name_partial(v)?.into()))
96+
}
97+
}
98+
99+
impl TryFrom<String> for PartialNameRef<'static> {
100+
type Error = Error;
101+
102+
fn try_from(v: String) -> Result<Self, Self::Error> {
103+
git_validate::reference::name_partial(v.as_bytes().as_bstr())?;
104+
Ok(PartialNameRef(BString::from(v).into()))
105+
}
106+
}
107+
108+
impl TryFrom<BString> for PartialNameRef<'static> {
109+
type Error = Error;
110+
111+
fn try_from(v: BString) -> Result<Self, Self::Error> {
112+
git_validate::reference::name_partial(v.as_ref())?;
113+
Ok(PartialNameRef(v.into()))
96114
}
97115
}

git-ref/src/store/file/find.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl file::Store {
125125
None => relative_path,
126126
Some(namespace) => namespace.to_owned().into_namespaced_prefix(relative_path),
127127
});
128-
let full_name = PartialNameRef((*full_name).as_bstr());
128+
let full_name = PartialNameRef((*full_name).as_bstr().into());
129129
if let Some(packed_ref) = packed.try_find(full_name)? {
130130
let mut res: Reference = packed_ref.into();
131131
if let Some(namespace) = &self.namespace {

git-ref/src/store/packed/find.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl packed::Buffer {
1515
let name = name.try_into()?;
1616
for inbetween in &["", "tags", "heads", "remotes"] {
1717
let (name, was_absolute) = if name.0.starts_with_str(b"refs/") {
18-
(Cow::Borrowed(name.0), true)
18+
(Cow::Borrowed(name.0.as_ref()), true)
1919
} else {
2020
let mut full_name: BString = format!(
2121
"refs/{}",
@@ -26,7 +26,7 @@ impl packed::Buffer {
2626
}
2727
)
2828
.into();
29-
full_name.extend_from_slice(name.0);
29+
full_name.extend_from_slice(name.0.as_ref());
3030
(Cow::Owned(full_name), false)
3131
};
3232
match self.binary_search_by(name.as_ref()) {

git-repository/tests/easy/reference.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ mod find {
3535
fn to_partial_name(&self) -> String {
3636
format!("{}/{}", self.remote, self.branch)
3737
}
38+
fn to_partial_name_from_string(&self) -> git_ref::PartialNameRef<'static> {
39+
self.to_partial_name().try_into().expect("cannot fail")
40+
}
41+
fn to_partial_name_from_bstring(&self) -> git_ref::PartialNameRef<'static> {
42+
git_object::bstr::BString::from(self.to_partial_name())
43+
.try_into()
44+
.expect("cannot fail")
45+
}
3846
fn to_full_name(&self) -> git_ref::FullName {
3947
format!("{}/{}", self.remote, self.branch)
4048
.try_into()
@@ -46,6 +54,9 @@ mod find {
4654
branch: "main",
4755
};
4856
repo.find_reference(&name.to_partial_name())?;
57+
repo.find_reference(name.to_partial_name())?;
58+
repo.find_reference(name.to_partial_name_from_string())?;
59+
repo.find_reference(name.to_partial_name_from_bstring())?;
4960
repo.find_reference(name.to_full_name().to_partial())?;
5061

5162
Ok(())

0 commit comments

Comments
 (0)