Gitbutler >:(
I don't understand this piece of software at all
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
/// Utility functions to get rid of tedious explicit casts to
|
||||
/// BoxedIter
|
||||
use std::iter;
|
||||
|
||||
/// A trait object of [Iterator] to be assigned to variables that may be
|
||||
/// initialized form multiple iterators of incompatible types
|
||||
pub type BoxedIter<'a, T> = Box<dyn Iterator<Item = T> + 'a>;
|
||||
/// creates a [BoxedIter] of a single element
|
||||
pub fn box_once<'a, T: 'a>(t: T) -> BoxedIter<'a, T> { Box::new(iter::once(t)) }
|
||||
/// creates an empty [BoxedIter]
|
||||
pub fn box_empty<'a, T: 'a>() -> BoxedIter<'a, T> { Box::new(iter::empty()) }
|
||||
|
||||
/// Chain various iterators into a [BoxedIter]
|
||||
macro_rules! box_chain {
|
||||
($curr:expr) => {
|
||||
Box::new($curr) as BoxedIter<_>
|
||||
};
|
||||
($curr:expr, $($rest:expr),*) => {
|
||||
Box::new($curr$(.chain($rest))*) as $crate::utils::boxed_iter::BoxedIter<_>
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use box_chain;
|
||||
@@ -1,97 +0,0 @@
|
||||
//! Named left/right. I tried bools, I couldn't consistently remember which one
|
||||
//! is left, so I made an enum. Rust should optimize this into a bool anyway.
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::Not;
|
||||
|
||||
use super::boxed_iter::BoxedIter;
|
||||
|
||||
/// A primitive for encoding the two sides Left and Right. While booleans
|
||||
/// are technically usable for this purpose, they're very easy to confuse
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Side {
|
||||
/// Left, low, or high-to-low in the case of sequences
|
||||
Left,
|
||||
/// Right, high, or low-to-high in the case of sequences
|
||||
Right,
|
||||
}
|
||||
|
||||
impl fmt::Display for Side {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Left => write!(f, "Left"),
|
||||
Self::Right => write!(f, "Right"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Side {
|
||||
/// Get the side that is not the current one
|
||||
pub fn opposite(&self) -> Self {
|
||||
match self {
|
||||
Self::Left => Self::Right,
|
||||
Self::Right => Self::Left,
|
||||
}
|
||||
}
|
||||
/// Shorthand for opposite
|
||||
pub fn inv(&self) -> Self { self.opposite() }
|
||||
/// take N elements from this end of a slice
|
||||
pub fn slice<'a, T>(&self, size: usize, slice: &'a [T]) -> &'a [T] {
|
||||
match self {
|
||||
Side::Left => &slice[..size],
|
||||
Side::Right => &slice[slice.len() - size..],
|
||||
}
|
||||
}
|
||||
/// ignore N elements from this end of a slice
|
||||
pub fn crop<'a, T>(&self, margin: usize, slice: &'a [T]) -> &'a [T] {
|
||||
self.opposite().slice(slice.len() - margin, slice)
|
||||
}
|
||||
/// ignore N elements from this end and M elements from the other end
|
||||
/// of a slice
|
||||
pub fn crop_both<'a, T>(&self, margin: usize, opposite: usize, slice: &'a [T]) -> &'a [T] {
|
||||
self.crop(margin, self.opposite().crop(opposite, slice))
|
||||
}
|
||||
/// Pick this side from a pair of things
|
||||
pub fn pick<T>(&self, pair: (T, T)) -> T {
|
||||
match self {
|
||||
Side::Left => pair.0,
|
||||
Side::Right => pair.1,
|
||||
}
|
||||
}
|
||||
/// Make a pair with the first element on this side
|
||||
pub fn pair<T>(&self, this: T, opposite: T) -> (T, T) {
|
||||
match self {
|
||||
Side::Left => (this, opposite),
|
||||
Side::Right => (opposite, this),
|
||||
}
|
||||
}
|
||||
/// Walk a double ended iterator (assumed to be left-to-right) in this
|
||||
/// direction
|
||||
pub fn walk<'a, I: DoubleEndedIterator + 'a>(&self, iter: I) -> BoxedIter<'a, I::Item> {
|
||||
match self {
|
||||
Side::Right => Box::new(iter) as BoxedIter<I::Item>,
|
||||
Side::Left => Box::new(iter.rev()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Not for Side {
|
||||
type Output = Side;
|
||||
|
||||
fn not(self) -> Self::Output { self.opposite() }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// I apparently have a tendency to mix these up so it's best if
|
||||
/// the sides are explicitly stated
|
||||
#[test]
|
||||
fn test_walk() {
|
||||
assert_eq!(Side::Right.walk(0..4).collect_vec(), vec![0, 1, 2, 3], "can walk a range");
|
||||
assert_eq!(Side::Left.walk(0..4).collect_vec(), vec![3, 2, 1, 0], "can walk a range backwards")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user