moq_transfork/model/
path.rs

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::fmt;

#[derive(Clone, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Path {
	parts: Vec<String>,
}

impl Path {
	pub const fn new() -> Self {
		Self { parts: Vec::new() }
	}

	pub fn push<T: ToString>(mut self, part: T) -> Self {
		self.parts.push(part.to_string());
		self
	}

	pub fn append(mut self, other: &Self) -> Self {
		self.parts.extend_from_slice(&other.parts);
		self
	}

	pub fn has_prefix(&self, prefix: &Path) -> bool {
		if prefix.parts.len() > self.parts.len() {
			return false;
		}

		prefix.parts.iter().zip(self.parts.iter()).all(|(a, b)| a == b)
	}

	pub fn strip_prefix(mut self, prefix: &Path) -> Option<Self> {
		if !self.has_prefix(prefix) {
			return None;
		}

		self.parts.drain(..prefix.parts.len());
		Some(self)
	}

	pub fn has_suffix(&self, suffix: &Path) -> bool {
		if suffix.parts.len() > self.parts.len() {
			return false;
		}

		suffix
			.parts
			.iter()
			.rev()
			.zip(self.parts.iter().rev())
			.all(|(a, b)| a == b)
	}

	pub fn strip_suffix(mut self, suffix: &Path) -> Option<Self> {
		if !self.has_suffix(suffix) {
			return None;
		}

		self.parts.drain(self.parts.len() - suffix.parts.len()..);
		Some(self)
	}
}

impl std::ops::Deref for Path {
	type Target = Vec<String>;

	fn deref(&self) -> &Self::Target {
		&self.parts
	}
}

impl std::ops::DerefMut for Path {
	fn deref_mut(&mut self) -> &mut Self::Target {
		&mut self.parts
	}
}

impl fmt::Debug for Path {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "[")?;
		for (i, part) in self.parts.iter().enumerate() {
			if i > 0 {
				write!(f, ", ")?;
			}
			write!(f, "{:?}", part)?;
		}
		write!(f, "]")
	}
}

impl<S: ToString> FromIterator<S> for Path {
	fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
		Self {
			parts: iter.into_iter().map(|t| t.to_string()).collect(),
		}
	}
}

impl From<Vec<String>> for Path {
	fn from(parts: Vec<String>) -> Self {
		Self { parts }
	}
}