iref_core/iri/
path_mut.rs1use crate::common::path_mut::PathMutImpl;
2use std::ops::Deref;
3
4use super::{path::Segment, Path, PathBuf};
5
6pub struct PathMut<'a>(PathMutImpl<'a, Path>);
8
9impl<'a> Deref for PathMut<'a> {
10 type Target = Path;
11
12 fn deref(&self) -> &Self::Target {
13 self.0.deref()
14 }
15}
16
17impl<'a> PathMut<'a> {
18 pub unsafe fn new(buffer: &'a mut Vec<u8>, start: usize, end: usize) -> Self {
25 Self(PathMutImpl::new(buffer, start, end))
26 }
27
28 pub(crate) fn from_impl(i: PathMutImpl<'a, Path>) -> Self {
29 Self(i)
30 }
31
32 pub fn from_path(path: &'a mut PathBuf) -> Self {
33 Self(PathMutImpl::from_path(path))
34 }
35
36 pub fn push(&mut self, segment: &Segment) {
66 self.0.push(segment)
67 }
68
69 pub fn pop(&mut self) {
74 self.0.pop();
75 }
76
77 pub fn clear(&mut self) {
78 self.0.clear()
79 }
80
81 #[inline]
83 pub fn symbolic_push(&mut self, segment: &Segment) {
84 if self.0.symbolic_push(segment) && !self.0.is_empty() {
85 self.0.push(Segment::EMPTY)
86 }
87 }
88
89 #[inline]
95 pub fn symbolic_append<'s, P: IntoIterator<Item = &'s Segment>>(&mut self, path: P) {
96 self.0.symbolic_append(path)
97 }
98
99 #[inline]
100 pub fn normalize(&mut self) {
101 self.0.normalize()
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn push() {
111 let vectors = [
112 ("", "foo", "foo"),
113 ("/", "foo", "/foo"),
114 ("", "", "./"),
115 ("/", "", "/./"),
116 ("foo", "bar", "foo/bar"),
117 ("/foo", "bar", "/foo/bar"),
118 ("foo", "", "foo/"),
119 ("foo/bar", "", "foo/bar/"),
120 ("foo/", "", "foo//"),
121 ("a/b/c", "d", "a/b/c/d"),
122 ("/a/b/c", "d", "/a/b/c/d"),
123 ("a/b/c/", "d", "a/b/c//d"),
124 ];
125
126 for (path, segment, expected) in vectors {
127 let mut path = PathBuf::new(path.to_string()).unwrap();
128 let mut path_mut = PathMut::from_path(&mut path);
129 let segment = Segment::new(&segment).unwrap();
130 path_mut.push(segment);
131 assert_eq!(path_mut.as_str(), expected)
132 }
133 }
134
135 #[test]
136 fn pop() {
137 let vectors = [
138 ("", ".."),
139 ("/", "/"),
140 ("/..", "/../.."),
141 ("foo", ""),
142 ("foo/bar", "foo"),
143 ("foo/bar/", "foo/bar"),
144 ];
145
146 for (path, expected) in vectors {
147 let mut path = PathBuf::new(path.to_string()).unwrap();
148 let mut path_mut = PathMut::from_path(&mut path);
149 path_mut.pop();
150 assert_eq!(path_mut.as_str(), expected)
151 }
152 }
153
154 #[test]
155 fn normalized() {
156 let vectors = [
157 ("", ""),
158 ("a/b/c", "a/b/c"),
159 ("a/..", ""),
160 ("a/b/..", "a"),
161 ("a/b/../", "a/"),
162 ("a/b/c/..", "a/b"),
163 ("a/b/c/.", "a/b/c"),
164 ("a/../..", ".."),
165 ("/a/../..", "/"),
166 ];
167
168 for (input, expected) in vectors {
169 let mut path = PathBuf::new(input.to_string()).unwrap();
170 let mut path_mut = PathMut::from_path(&mut path);
171 path_mut.normalize();
172 assert_eq!(path_mut.as_str(), expected);
173 }
174 }
175}