This makes it easier to make changes to entries of a certain prefix.
Unified · Split
| @@ -184,9 +184,18 @@ impl State { · 183 unmodified lines | |||
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | /// Return the slice of entries which all share the same `prefix`, or `None` if there isn't a single such entry. | 186 | /// Return the slice of entries which all share the same `prefix`, or `None` if there isn't a single such entry. |
| 187 | /// | ||
| 188 | /// If `prefix` is empty, all entries are returned. | ||
| 187 | pub fn prefixed_entries(&self, prefix: &BStr) -> Option<&[Entry]> { | 189 | pub fn prefixed_entries(&self, prefix: &BStr) -> Option<&[Entry]> { |
| 190 | self.prefixed_entries_range(prefix).map(|range| &self.entries[range]) | ||
| 191 | } | ||
| 192 | |||
| 193 | /// Return the range of entries which all share the same `prefix`, or `None` if there isn't a single such entry. | ||
| 194 | /// | ||
| 195 | /// If `prefix` is empty, the range will include all entries. | ||
| 196 | pub fn prefixed_entries_range(&self, prefix: &BStr) -> Option<Range<usize>> { | ||
| 188 | if prefix.is_empty() { | 197 | if prefix.is_empty() { |
| 189 | return Some(self.entries()); | 198 | return Some(0..self.entries.len()); |
| 190 | } | 199 | } |
| 191 | let prefix_len = prefix.len(); | 200 | let prefix_len = prefix.len(); |
| 192 | let mut low = self | 201 | let mut low = self |
| @@ -195,7 +204,7 @@ impl State { · 2 unmodified lines | |||
| 195 | let mut high = low | 204 | let mut high = low |
| 196 | + self.entries[low..].partition_point(|e| e.path(self).get(..prefix_len).map_or(false, |p| p <= prefix)); | 205 | + self.entries[low..].partition_point(|e| e.path(self).get(..prefix_len).map_or(false, |p| p <= prefix)); |
| 197 | 206 | ||
| 198 | let low_entry = &self.entries[low]; | 207 | let low_entry = &self.entries.get(low)?; |
| 199 | if low_entry.stage() != 0 { | 208 | if low_entry.stage() != 0 { |
| 200 | low = self | 209 | low = self |
| 201 | .walk_entry_stages(low_entry.path(self), low, Ordering::Less) | 210 | .walk_entry_stages(low_entry.path(self), low, Ordering::Less) |
| @@ -208,7 +217,7 @@ impl State { · 6 unmodified lines | |||
| 208 | .unwrap_or(high); | 217 | .unwrap_or(high); |
| 209 | } | 218 | } |
| 210 | } | 219 | } |
| 211 | (low != high).then_some(low..high).map(|range| &self.entries[range]) | 220 | (low != high).then_some(low..high) |
| 212 | } | 221 | } |
| 213 | 222 | ||
| 214 | /// Return the entry at `idx` or _panic_ if the index is out of bounds. | 223 | /// Return the entry at `idx` or _panic_ if the index is out of bounds. |
| @@ -50,6 +50,8 @@ fn prefixed_entries_with_multi_stage_file() { · 49 unmodified lines | |||
| 50 | file.entries(), | 50 | file.entries(), |
| 51 | "empty prefix matches all" | 51 | "empty prefix matches all" |
| 52 | ); | 52 | ); |
| 53 | assert_eq!(file.prefixed_entries_range("".into()), Some(0..3)); | ||
| 54 | assert_eq!(file.prefixed_entries_range("foo".into()), None); | ||
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | #[test] | 57 | #[test] |