caco 0.5.33

library for dealing with doom [et al] wad files
Documentation
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
    }
}