radicle_git_ref_format/name/
iter.rs1use std::{
2 borrow::Cow,
3 fmt::{self, Display},
4 ops::Deref,
5};
6
7use super::RefStr;
8use crate::lit;
9
10pub type Iter<'a> = std::str::Split<'a, char>;
11
12#[must_use = "iterators are lazy and do nothing unless consumed"]
14#[derive(Clone)]
15pub struct Components<'a> {
16 inner: std::str::Split<'a, char>,
17}
18
19impl<'a> Iterator for Components<'a> {
20 type Item = Component<'a>;
21
22 #[inline]
23 fn next(&mut self) -> Option<Self::Item> {
24 self.inner
25 .next()
26 .map(RefStr::from_str)
27 .map(Cow::from)
28 .map(Component)
29 }
30}
31
32impl DoubleEndedIterator for Components<'_> {
33 #[inline]
34 fn next_back(&mut self) -> Option<Self::Item> {
35 self.inner
36 .next_back()
37 .map(RefStr::from_str)
38 .map(Cow::from)
39 .map(Component)
40 }
41}
42
43impl<'a> From<&'a RefStr> for Components<'a> {
44 #[inline]
45 fn from(rs: &'a RefStr) -> Self {
46 Self {
47 inner: rs.as_str().split('/'),
48 }
49 }
50}
51
52#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
57pub struct Component<'a>(Cow<'a, RefStr>);
58
59impl<'a> Component<'a> {
60 #[inline]
61 pub fn from_refstr(r: impl Into<Cow<'a, RefStr>>) -> Option<Self> {
62 let r = r.into();
63 if !r.contains('/') {
64 Some(Self(r))
65 } else {
66 None
67 }
68 }
69
70 #[inline]
71 pub fn as_lit<T: lit::Lit>(&self) -> Option<T> {
72 T::from_component(self)
73 }
74
75 #[inline]
76 pub fn into_inner(self) -> Cow<'a, RefStr> {
77 self.0
78 }
79}
80
81impl Deref for Component<'_> {
82 type Target = RefStr;
83
84 #[inline]
85 fn deref(&self) -> &Self::Target {
86 &self.0
87 }
88}
89
90impl AsRef<RefStr> for Component<'_> {
91 #[inline]
92 fn as_ref(&self) -> &RefStr {
93 self
94 }
95}
96
97impl<'a> From<&'a RefStr> for Option<Component<'a>> {
98 #[inline]
99 fn from(r: &'a RefStr) -> Self {
100 if !r.contains('/') {
101 Some(Component(Cow::from(r)))
102 } else {
103 None
104 }
105 }
106}
107
108impl<'a> From<Component<'a>> for Cow<'a, RefStr> {
109 #[inline]
110 fn from(c: Component<'a>) -> Self {
111 c.0
112 }
113}
114
115impl<T: lit::Lit> From<T> for Component<'static> {
116 #[inline]
117 fn from(_: T) -> Self {
118 Component(Cow::from(T::NAME))
119 }
120}
121
122impl<'a> From<lit::SomeLit<'a>> for Component<'a> {
123 #[inline]
124 fn from(s: lit::SomeLit<'a>) -> Self {
125 use lit::SomeLit::*;
126
127 match s {
128 Known(k) => k.into(),
129 Any(c) => c,
130 }
131 }
132}
133
134impl Display for Component<'_> {
135 #[inline]
136 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137 f.write_str(self.0.as_str())
138 }
139}
140
141pub mod component {
142 use super::Component;
143 use crate::name;
144 use std::borrow::Cow;
145
146 pub const HEADS: Component = Component(Cow::Borrowed(name::HEADS));
147 pub const MAIN: Component = Component(Cow::Borrowed(name::MAIN));
148 pub const MASTER: Component = Component(Cow::Borrowed(name::MASTER));
149 pub const NAMESPACES: Component = Component(Cow::Borrowed(name::NAMESPACES));
150 pub const NOTES: Component = Component(Cow::Borrowed(name::NOTES));
151 pub const ORIGIN: Component = Component(Cow::Borrowed(name::ORIGIN));
152 pub const REFS: Component = Component(Cow::Borrowed(name::REFS));
153 pub const REMOTES: Component = Component(Cow::Borrowed(name::REMOTES));
154 pub const TAGS: Component = Component(Cow::Borrowed(name::TAGS));
155}