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
use crate::agnostic::{ClumpMut, FlatClod};
#[cfg(feature = "regex")]
use regex::Regex;
/// A mutable version of [`FlatClod`], or alternatively, a flat (subdirectory-less) version of [`ClodMut`](crate::agnostic::ClodMut).
pub trait FlatClodMut<Q>: FlatClod<Q> where Q: ClumpMut {
/// Mutably borrows a single clump by number.
fn nth_clump_mut(&mut self, n: usize) -> &mut Q;
/// Mutably borrows many clumps by numbers. The range may be non-contiguous. The returned clumps are always
/// in numerically increasing order, and are not duplicated, regardless of the ordering or
/// overlapping of the provided range(s).
fn a_sub_nth_clumps_mut(&mut self, a: impl Iterator<Item = usize>) -> Vec<&mut Q>;
/// Insert a clump into the clod at the specified position.
fn insert_clump(&mut self, l: Q, n: usize);
// Remove the clump at the specified position, returning it.
fn remove_clump(&mut self, n: usize) -> Q;
// -------------------------------------------------------------------------------------------------------
// PROVIDED:
/// Borrows every clump.
fn all_clumps_mut(&mut self) -> Vec<&mut Q> {
let i = self.clump_amt();
self.a_sub_nth_clumps_mut(0..i)
}
/// Mutably borrow every clump with the specified name. The clumps will be in numerically increasing order
/// by their index in the clod.
fn clumps_with_name_mut(&mut self, s: impl AsRef<str>) -> Vec<&mut Q> {
let a_n: Vec<usize> = self.which_clumps(s);
self.a_sub_nth_clumps_mut(a_n.into_iter())
}
/// Mutably borrow a clump by it's specific name. If multiple clumps with the name exist, returns the first one.
/// If no clumps with the name exist, returns [`None`].
fn clump_by_name_mut(&mut self, s: impl AsRef<str>) -> Option<&mut Q> {
// todo: can it be done with a one-liner? (i.e. no `let`?)
let mut v = self.clumps_with_name_mut(s);
if v.len() == 0 { None } else { Some(v.remove(0)) }
}
/// Mutably borrow every clump matching the specified regex pattern. The clumps will be in numerically
/// increasing order by their index in the clod.
#[cfg(feature = "regex")]
fn clumps_with_name_re_mut(&mut self, r: Regex) -> Vec<&mut Q> {
let a_n: Vec<usize> = self.which_clumps_re(r);
self.a_sub_nth_clumps_mut(a_n.into_iter())
}
/// Mutably borrow a clump, matching with a specific regex. If multiple matching clumps exist, returns the first one.
/// If no clumps matching the pattern exist, returns [`None`].
#[cfg(feature = "regex")]
fn clump_by_name_re_mut(&mut self, r: Regex) -> Option<&mut Q> {
// todo: can it be done with a one-liner? (i.e. no `let`?)
let mut v = self.clumps_with_name_re_mut(r);
if v.len() == 0 { None } else { Some(v.remove(0)) }
}
/// Mutably borrows all clumps between the given markers, sorted numerically by index.
fn clumps_between_markers_mut(&mut self, start: impl AsRef<str>, end: impl AsRef<str>) -> Vec<&mut Q> {
self.a_sub_nth_clumps_mut(self.indices_between_markers(start, end).iter().map(|n| *n))
}
/// Add a clump to the clod at the end.
fn append_clump(&mut self, l: Q) {
self.insert_clump(l, self.clump_amt());
}
/// Insert a series of clumps at the specified position.
fn inject_clumps(&mut self, ls: impl Iterator<Item = Q>, n: usize) {
let ls = ls.collect::<Vec<Q>>();
for (k, kl) in (n..n+ls.len()).zip(ls) {
self.insert_clump(kl, k);
}
}
/// Remove a set of clumps specified by the range provided.
fn extract_clumps(&mut self, a: impl Iterator<Item = usize>) -> Vec<Q> {
let mut w = vec!();
for a_n in a {
w.push(self.remove_clump(a_n));
}
w
}
}