Skip to content

Commit 249bf9a

Browse files
authored
Merge pull request #2036 from GitoxideLabs/improvements
improvements
2 parents f8d7c0a + f8b87f1 commit 249bf9a

File tree

4 files changed

+93
-5
lines changed

4 files changed

+93
-5
lines changed

gix-actor/src/identity.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ mod write {
5353
}
5454

5555
mod impls {
56-
use crate::{Identity, IdentityRef};
56+
use crate::{Identity, IdentityRef, Signature, SignatureRef};
5757

5858
impl Identity {
5959
/// Borrow this instance as immutable
@@ -80,4 +80,16 @@ mod impls {
8080
other.to_ref()
8181
}
8282
}
83+
84+
impl From<Signature> for Identity {
85+
fn from(Signature { name, email, time: _ }: Signature) -> Self {
86+
Identity { name, email }
87+
}
88+
}
89+
90+
impl<'a> From<SignatureRef<'a>> for IdentityRef<'a> {
91+
fn from(SignatureRef { name, email, time: _ }: SignatureRef<'a>) -> Self {
92+
IdentityRef { name, email }
93+
}
94+
}
8395
}

gix-ref/src/fullname.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,35 @@ impl FullNameRef {
156156
}
157157
}
158158

159+
/// Conversion
160+
impl Category<'_> {
161+
/// As the inverse of [`FullNameRef::category_and_short_name()`], use the prefix of this category alongside
162+
/// the `short_name` to create a valid fully qualified [reference name](FullName).
163+
pub fn to_full_name<'a>(&self, short_name: impl Into<&'a BStr>) -> Result<FullName, crate::name::Error> {
164+
let mut out: BString = self.prefix().into();
165+
let short_name = short_name.into();
166+
let partial_name = match self {
167+
Category::Note => short_name.strip_prefix("notes/".as_bytes()).unwrap_or(short_name),
168+
Category::MainRef => short_name.strip_prefix("refs/".as_bytes()).unwrap_or(short_name),
169+
Category::LinkedPseudoRef { name } | Category::LinkedRef { name } => {
170+
out.extend_from_slice(name);
171+
out.push(b'/');
172+
short_name
173+
}
174+
Category::Bisect => short_name.strip_prefix("bisect/".as_bytes()).unwrap_or(short_name),
175+
Category::Rewritten => short_name.strip_prefix("rewritten/".as_bytes()).unwrap_or(short_name),
176+
Category::WorktreePrivate => short_name.strip_prefix("worktree/".as_bytes()).unwrap_or(short_name),
177+
Category::Tag
178+
| Category::LocalBranch
179+
| Category::RemoteBranch
180+
| Category::PseudoRef
181+
| Category::MainPseudoRef => short_name,
182+
};
183+
out.extend_from_slice(partial_name);
184+
FullName::try_from(out)
185+
}
186+
}
187+
159188
impl FullName {
160189
/// Convert this name into the relative path, lossily, identifying the reference location relative to a repository
161190
pub fn to_path(&self) -> &Path {

gix-ref/tests/refs/fullname.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,23 @@ fn shorten_and_category() {
8181
assert_eq!(name.as_ref().shorten(), expected);
8282
assert_eq!(name.shorten(), expected);
8383
assert_eq!(name.category(), category);
84-
assert_eq!(
85-
name.category_and_short_name(),
86-
category.map(|cat| (cat, expected.into()))
87-
);
84+
85+
let cat_and_short_name = name.category_and_short_name();
86+
match category {
87+
None => {
88+
assert_eq!(cat_and_short_name, None);
89+
}
90+
Some(expected_category) => {
91+
assert_eq!(cat_and_short_name, Some((expected_category, expected.into())));
92+
let (cat, short_name) = cat_and_short_name.expect("we know it's set");
93+
let actual = cat.to_full_name(short_name).expect("valid input = valid output");
94+
assert_eq!(
95+
actual.as_ref().as_bstr(),
96+
input,
97+
"{input}: {cat:?}:{short_name}: categories and short-names can round-trip"
98+
);
99+
}
100+
}
88101
assert_eq!(name.as_ref().category(), category);
89102
}
90103

@@ -97,6 +110,11 @@ fn shorten_and_category() {
97110
);
98111
assert_eq!(name.category(), None);
99112
}
113+
114+
assert!(
115+
Category::LocalBranch.to_full_name("invalid/").is_err(),
116+
"validation is performed as one would expect"
117+
);
100118
}
101119

102120
#[test]

gix-ref/tests/refs/main.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,35 @@ pub use gix_testtools::Result;
88

99
mod file;
1010
mod fullname;
11+
mod partialname {
12+
use gix_ref::PartialName;
13+
14+
#[test]
15+
fn join() -> crate::Result {
16+
let pn = PartialName::try_from("no-trailing-slash")?;
17+
assert_eq!(pn.join("name".into())?.as_ref().as_bstr(), "no-trailing-slash/name");
18+
19+
let err = PartialName::try_from("trailing-slash/").unwrap_err();
20+
assert!(
21+
matches!(
22+
err,
23+
gix_validate::reference::name::Error::Tag(gix_validate::tag::name::Error::EndsWithSlash)
24+
),
25+
"thanks to this there is no worry about dealing with this case"
26+
);
27+
28+
let pn = PartialName::try_from("prefix")?;
29+
let err = pn.join("/slash-in-name".into()).unwrap_err();
30+
assert!(
31+
matches!(
32+
err,
33+
gix_validate::reference::name::Error::Tag(gix_validate::tag::name::Error::RepeatedSlash)
34+
),
35+
"validation post-join assures the returned type is valid"
36+
);
37+
Ok(())
38+
}
39+
}
1140
mod namespace;
1241
mod packed;
1342
mod reference;

0 commit comments

Comments
 (0)