iref_core/uri/
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(crate) fn from_impl(i: PathMutImpl<'a, Path>) -> Self {
19 Self(i)
20 }
21
22 pub fn from_path(path: &'a mut PathBuf) -> Self {
23 Self(PathMutImpl::from_path(path))
24 }
25
26 pub fn push(&mut self, segment: &Segment) {
56 self.0.push(segment)
57 }
58
59 pub fn pop(&mut self) {
64 self.0.pop();
65 }
66
67 pub fn clear(&mut self) {
68 self.0.clear()
69 }
70
71 #[inline]
73 pub fn symbolic_push(&mut self, segment: &Segment) {
74 if self.0.symbolic_push(segment) && !self.0.is_empty() {
75 self.0.push(Segment::EMPTY)
76 }
77 }
78
79 #[inline]
85 pub fn symbolic_append<'s, P: IntoIterator<Item = &'s Segment>>(&mut self, path: P) {
86 self.0.symbolic_append(path)
87 }
88
89 #[inline]
90 pub fn normalize(&mut self) {
91 self.0.normalize()
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn push() {
101 let vectors: [(&[u8], &[u8], &[u8]); 12] = [
102 (b"", b"foo", b"foo"),
103 (b"/", b"foo", b"/foo"),
104 (b"", b"", b"./"),
105 (b"/", b"", b"/./"),
106 (b"foo", b"bar", b"foo/bar"),
107 (b"/foo", b"bar", b"/foo/bar"),
108 (b"foo", b"", b"foo/"),
109 (b"foo/bar", b"", b"foo/bar/"),
110 (b"foo/", b"", b"foo//"),
111 (b"a/b/c", b"d", b"a/b/c/d"),
112 (b"/a/b/c", b"d", b"/a/b/c/d"),
113 (b"a/b/c/", b"d", b"a/b/c//d"),
114 ];
115
116 for (path, segment, expected) in vectors {
117 let mut path = PathBuf::new(path.to_vec()).unwrap();
118 let mut path_mut = PathMut::from_path(&mut path);
119 let segment = Segment::new(&segment).unwrap();
120 path_mut.push(segment);
121 assert_eq!(path_mut.as_bytes(), expected)
122 }
123 }
124
125 #[test]
126 fn pop() {
127 let vectors: [(&[u8], &[u8]); 6] = [
128 (b"", b".."),
129 (b"/", b"/"),
130 (b"/..", b"/../.."),
131 (b"foo", b""),
132 (b"foo/bar", b"foo"),
133 (b"foo/bar/", b"foo/bar"),
134 ];
135
136 for (path, expected) in vectors {
137 let mut path = PathBuf::new(path.to_vec()).unwrap();
138 let mut path_mut = PathMut::from_path(&mut path);
139 path_mut.pop();
140 assert_eq!(path_mut.as_bytes(), expected)
141 }
142 }
143
144 #[test]
145 fn normalized() {
146 let vectors: [(&[u8], &[u8]); 9] = [
147 (b"", b""),
148 (b"a/b/c", b"a/b/c"),
149 (b"a/..", b""),
150 (b"a/b/..", b"a"),
151 (b"a/b/../", b"a/"),
152 (b"a/b/c/..", b"a/b"),
153 (b"a/b/c/.", b"a/b/c"),
154 (b"a/../..", b".."),
155 (b"/a/../..", b"/"),
156 ];
157
158 for (input, expected) in vectors {
159 let mut path = PathBuf::new(input.to_vec()).unwrap();
160 let mut path_mut = PathMut::from_path(&mut path);
161 path_mut.normalize();
162 assert_eq!(path_mut.as_bytes(), expected);
163 }
164 }
165}