1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
use std::{borrow::Cow, convert::TryFrom};
use super::Name;
use crate::bstr::{BStr, BString, ByteSlice, ByteVec};
/// The error returned by [validated()].
#[derive(Debug, thiserror::Error)]
#[error("remote names must be valid within refspecs for fetching: {name:?}")]
#[allow(missing_docs)]
pub struct Error {
pub source: gix_refspec::parse::Error,
pub name: BString,
}
/// Return `name` if it is valid as symbolic remote name.
///
/// This means it has to be valid within a the ref path of a tracking branch.
pub fn validated(name: impl Into<BString>) -> Result<BString, Error> {
let name = name.into();
match gix_refspec::parse(
format!("refs/heads/test:refs/remotes/{name}/test").as_str().into(),
gix_refspec::parse::Operation::Fetch,
) {
Ok(_) => Ok(name),
Err(err) => Err(Error { source: err, name }),
}
}
impl Name<'_> {
/// Obtain the name as string representation.
pub fn as_bstr(&self) -> &BStr {
match self {
Name::Symbol(v) => v.as_ref().into(),
Name::Url(v) => v.as_ref(),
}
}
/// Return this instance as a symbolic name, if it is one.
pub fn as_symbol(&self) -> Option<&str> {
match self {
Name::Symbol(n) => n.as_ref().into(),
Name::Url(_) => None,
}
}
/// Return this instance as url, if it is one.
pub fn as_url(&self) -> Option<&BStr> {
match self {
Name::Url(n) => n.as_ref().into(),
Name::Symbol(_) => None,
}
}
}
impl<'a> TryFrom<Cow<'a, BStr>> for Name<'a> {
type Error = Cow<'a, BStr>;
fn try_from(name: Cow<'a, BStr>) -> Result<Self, Self::Error> {
if name.contains(&b'/') || name.as_ref() == "." {
Ok(Name::Url(name))
} else {
match name {
Cow::Borrowed(n) => n.to_str().ok().map(Cow::Borrowed).ok_or(name),
Cow::Owned(n) => Vec::from(n)
.into_string()
.map_err(|err| Cow::Owned(err.into_vec().into()))
.map(Cow::Owned),
}
.map(Name::Symbol)
}
}
}
impl From<BString> for Name<'static> {
fn from(name: BString) -> Self {
Self::try_from(Cow::Owned(name)).expect("String is never illformed")
}
}
impl<'a> AsRef<BStr> for Name<'a> {
fn as_ref(&self) -> &BStr {
self.as_bstr()
}
}
|