summaryrefslogtreecommitdiffstats
path: root/vendor/array_tool/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/array_tool/src
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/array_tool/src')
-rw-r--r--vendor/array_tool/src/iter.rs166
-rw-r--r--vendor/array_tool/src/lib.rs58
-rw-r--r--vendor/array_tool/src/string.rs303
-rw-r--r--vendor/array_tool/src/vec.rs318
4 files changed, 0 insertions, 845 deletions
diff --git a/vendor/array_tool/src/iter.rs b/vendor/array_tool/src/iter.rs
deleted file mode 100644
index a176d5c79..000000000
--- a/vendor/array_tool/src/iter.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-use std::cmp;
-use std::iter::IntoIterator;
-
-#[doc(hidden)]
-#[derive(Clone, Debug)]
-#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
-pub struct ZipOption<A, B> {
- a: A,
- b: B,
- // index and len are only used by the specialized version of zip
- index: usize,
- len: usize,
-}
-
-/// Zips to iterators together to the longest length
-/// via Option<(Option<A>, Option<B>)>
-pub trait ZipOpt {
- /// Zip to iterators to longest length via Option<(Option<A>, Option<B>)> results.
- /// # Example
- /// ```
- /// use array_tool::iter::ZipOpt;
- ///
- /// let a = vec!["a","b","c", "d"];
- /// let b = vec!["c","d"];
- /// let mut x = a.iter().zip_option(b.iter());
- ///
- /// assert_eq!(x.next(), Some((Some(&"a"), Some(&"c"))));
- /// assert_eq!(x.next(), Some((Some(&"b"), Some(&"d"))));
- /// assert_eq!(x.next(), Some((Some(&"c"), None)));
- /// assert_eq!(x.next(), Some((Some(&"d"), None)));
- /// assert_eq!(x.next(), None);
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![ "a", "b", "c", "d" ]
- /// ```
- fn zip_option<U>(self, other: U) -> ZipOption<Self, U::IntoIter>
- where Self: Sized, U: IntoIterator;
-}
-
-impl<I: Iterator> ZipOpt for I {
- #[inline]
- fn zip_option<U>(self, other: U) -> ZipOption<Self, U::IntoIter>
- where Self: Sized, U: IntoIterator {
-
- ZipOption::new(self, other.into_iter())
- }
-}
-
-impl<A, B> Iterator for ZipOption<A, B> where A: Iterator, B: Iterator {
- type Item = (Option<A::Item>, Option<B::Item>);
-
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- ZipImpl::next(self)
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- ZipImpl::size_hint(self)
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- ZipImpl::nth(self, n)
- }
-}
-
-#[doc(hidden)]
-impl<A, B> DoubleEndedIterator for ZipOption<A, B> where
-A: DoubleEndedIterator + ExactSizeIterator,
-B: DoubleEndedIterator + ExactSizeIterator,
-{
- #[inline]
- fn next_back(&mut self) -> Option<(Option<A::Item>, Option<B::Item>)> {
- ZipImpl::next_back(self)
- }
-}
-
-#[doc(hidden)]
-trait ZipImpl<A, B> {
- type Item;
- fn new(a: A, b: B) -> Self;
- fn next(&mut self) -> Option<Self::Item>;
- fn size_hint(&self) -> (usize, Option<usize>);
- fn nth(&mut self, n: usize) -> Option<Self::Item>;
- fn super_nth(&mut self, mut n: usize) -> Option<Self::Item> {
- while let Some(x) = self.next() {
- if n == 0 { return Some(x) }
- n -= 1;
- }
- None
- }
- fn next_back(&mut self) -> Option<Self::Item>
- where A: DoubleEndedIterator + ExactSizeIterator,
- B: DoubleEndedIterator + ExactSizeIterator;
-}
-
-#[doc(hidden)]
-impl<A, B> ZipImpl<A, B> for ZipOption<A, B>
- where A: Iterator, B: Iterator {
- type Item = (Option<A::Item>, Option<B::Item>);
- fn new(a: A, b: B) -> Self {
- ZipOption {
- a,
- b,
- index: 0, // unused
- len: 0, // unused
- }
- }
-
- #[inline]
- fn next(&mut self) -> Option<(Option<A::Item>, Option<B::Item>)> {
- let first = self.a.next();
- let second = self.b.next();
-
- if first.is_some() || second.is_some() {
- Some((first, second))
- } else {
- None
- }
- }
-
- #[inline]
- fn nth(&mut self, n: usize) -> Option<Self::Item> {
- self.super_nth(n)
- }
-
- #[inline]
- fn next_back(&mut self) -> Option<(Option<A::Item>, Option<B::Item>)>
- where A: DoubleEndedIterator + ExactSizeIterator,
- B: DoubleEndedIterator + ExactSizeIterator {
- let a_sz = self.a.len();
- let b_sz = self.b.len();
- if a_sz != b_sz {
- // Adjust a, b to equal length
- if a_sz > b_sz {
- for _ in 0..a_sz - b_sz { self.a.next_back(); }
- } else {
- for _ in 0..b_sz - a_sz { self.b.next_back(); }
- }
- }
- match (self.a.next_back(), self.b.next_back()) {
- (None, None) => None,
- (f,s) => Some((f, s)),
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (a_lower, a_upper) = self.a.size_hint();
- let (b_lower, b_upper) = self.b.size_hint();
-
- let lower = cmp::min(a_lower, b_lower);
-
- let upper = match (a_upper, b_upper) {
- (Some(x), Some(y)) => Some(cmp::max(x,y)),
- (Some(x), None) => Some(x),
- (None, Some(y)) => Some(y),
- (None, None) => None
- };
-
- (lower, upper)
- }
-}
diff --git a/vendor/array_tool/src/lib.rs b/vendor/array_tool/src/lib.rs
deleted file mode 100644
index 5a7787f67..000000000
--- a/vendor/array_tool/src/lib.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-#![deny(missing_docs,trivial_casts,trivial_numeric_casts,
- missing_debug_implementations, missing_copy_implementations,
- unsafe_code,unused_import_braces,unused_qualifications)
-]
-// Copyright 2015-2017 Daniel P. Clark & array_tool Developers
-//
-// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
-// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
-// http://opensource.org/licenses/MIT>, at your option. This file may not be
-// copied, modified, or distributed except according to those terms.
-
-//! # Array Tool
-//!
-//! is a collection of powerful methods for working with collections.
-//! Some of the most common methods you would use on Arrays made available
-//! on Vectors. Polymorphic implementations for handling most of your use cases.
-//!
-//! In your rust files where you plan to use it put this at the top
-//!
-//! ```
-//! extern crate array_tool;
-//! ```
-//!
-//! And if you plan to use all of the Vector helper methods available:
-//!
-//! ```
-//! use array_tool::vec::*;
-//! ```
-//!
-//! This crate is not limited to just Vector methods and has some helpful
-//! string methods as well.
-
-
-/// Array Tool provides useful methods for iterators
-pub mod iter;
-/// Array Tool provides many useful methods for vectors
-pub mod vec;
-/// A string is a collection so we should have more methods for handling strings.
-pub mod string;
-
-/// Get `uniques` from two vectors
-///
-/// # Example
-/// ```
-/// use array_tool::uniques;
-///
-/// uniques(vec![1,2,3,4,5], vec![2,5,6,7,8]);
-/// ```
-///
-/// # Output
-/// ```text
-/// vec![vec![1,3,4], vec![6,7,8]]
-/// ```
-pub fn uniques<T: PartialEq + Clone>(a: Vec<T>, b: Vec<T>) -> Vec<Vec<T>> {
- use self::vec::Uniq;
- vec![a.uniq(b.clone()), b.uniq(a)]
-}
-
diff --git a/vendor/array_tool/src/string.rs b/vendor/array_tool/src/string.rs
deleted file mode 100644
index dc0e317ef..000000000
--- a/vendor/array_tool/src/string.rs
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright 2015-2017 Daniel P. Clark & array_tool Developers
-//
-// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
-// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
-// http://opensource.org/licenses/MIT>, at your option. This file may not be
-// copied, modified, or distributed except according to those terms.
-
-/// A grapheme iterator that produces the bytes for each grapheme.
-#[derive(Debug)]
-pub struct GraphemeBytesIter<'a> {
- source: &'a str,
- offset: usize,
- grapheme_count: usize,
-}
-impl<'a> GraphemeBytesIter<'a> {
- /// Creates a new grapheme iterator from a string source.
- pub fn new(source: &'a str) -> GraphemeBytesIter<'a> {
- GraphemeBytesIter {
- source: source,
- offset: 0,
- grapheme_count: 0,
- }
- }
-}
-impl<'a> Iterator for GraphemeBytesIter<'a> {
- type Item = &'a [u8];
-
- fn next(&mut self) -> Option<&'a [u8]> {
- let mut result: Option<&[u8]> = None;
- let mut idx = self.offset;
- for _ in self.offset..self.source.len() {
- idx += 1;
- if self.offset < self.source.len() {
- if self.source.is_char_boundary(idx) {
- let slice: &[u8] = self.source[self.offset..idx].as_bytes();
-
- self.grapheme_count += 1;
- self.offset = idx;
-
- result = Some(slice);
- break
- }
- }
- }
- result
- }
-}
-impl<'a> ExactSizeIterator for GraphemeBytesIter<'a> {
- fn len(&self) -> usize {
- self.source.chars().count()
- }
-}
-/// ToGraphemeBytesIter - create an iterator to return bytes for each grapheme in a string.
-pub trait ToGraphemeBytesIter<'a> {
- /// Returns a GraphemeBytesIter which you may iterate over.
- ///
- /// # Example
- /// ```
- /// use array_tool::string::ToGraphemeBytesIter;
- ///
- /// let string = "a s—d féZ";
- /// let mut graphemes = string.grapheme_bytes_iter();
- /// graphemes.skip(3).next();
- /// ```
- ///
- /// # Output
- /// ```text
- /// [226, 128, 148]
- /// ```
- fn grapheme_bytes_iter(&'a self) -> GraphemeBytesIter<'a>;
-}
-impl<'a> ToGraphemeBytesIter<'a> for str {
- fn grapheme_bytes_iter(&'a self) -> GraphemeBytesIter<'a> {
- GraphemeBytesIter::new(&self)
- }
-}
-
-/// Squeeze - squeezes duplicate characters down to one each
-pub trait Squeeze {
- /// # Example
- /// ```
- /// use array_tool::string::Squeeze;
- ///
- /// "yellow moon".squeeze("");
- /// ```
- ///
- /// # Output
- /// ```text
- /// "yelow mon"
- /// ```
- fn squeeze(&self, targets: &'static str) -> String;
-}
-impl Squeeze for str {
- fn squeeze(&self, targets: &'static str) -> String {
- let mut output = Vec::<u8>::with_capacity(self.len());
- let everything: bool = targets.is_empty();
- let chars = targets.grapheme_bytes_iter().collect::<Vec<&[u8]>>();
- let mut last: &[u8] = &[0];
- for character in self.grapheme_bytes_iter() {
- if last != character {
- output.extend_from_slice(character);
- } else if !(everything || chars.contains(&character)) {
- output.extend_from_slice(character);
- }
- last = character;
- }
- String::from_utf8(output).expect("squeeze failed to render String!")
- }
-}
-
-/// Justify - expand line to given width.
-pub trait Justify {
- /// # Example
- /// ```
- /// use array_tool::string::Justify;
- ///
- /// "asd asdf asd".justify_line(14);
- /// ```
- ///
- /// # Output
- /// ```text
- /// "asd asdf asd"
- /// ```
- fn justify_line(&self, width: usize) -> String;
-}
-
-impl Justify for str {
- fn justify_line(&self, width: usize) -> String {
- if self.is_empty() { return format!("{}", self) };
- let trimmed = self.trim() ;
- let len = trimmed.chars().count();
- if len >= width { return self.to_string(); };
- let difference = width - len;
- let iter = trimmed.split_whitespace();
- let spaces = iter.count() - 1;
- let mut iter = trimmed.split_whitespace().peekable();
- if spaces == 0 { return self.to_string(); }
- let mut obj = String::with_capacity(trimmed.len() + spaces);
-
- let div = difference / spaces;
- let mut remainder = difference % spaces;
-
- while let Some(x) = iter.next() {
- obj.push_str( x );
- let val = if remainder > 0 {
- remainder = remainder - 1;
- div + 1
- } else { div };
- for _ in 0..val+1 {
- if let Some(_) = iter.peek() { // Don't add spaces if last word
- obj.push_str( " " );
- }
- }
- }
- obj
- }
-}
-
-/// Substitute string character for each index given.
-pub trait SubstMarks {
- /// # Example
- /// ```
- /// use array_tool::string::SubstMarks;
- ///
- /// "asdf asdf asdf".subst_marks(vec![0,5,8], "Z");
- /// ```
- ///
- /// # Output
- /// ```text
- /// "Zsdf ZsdZ asdf"
- /// ```
- fn subst_marks(&self, marks: Vec<usize>, chr: &'static str) -> String;
-}
-impl SubstMarks for str {
- fn subst_marks(&self, marks: Vec<usize>, chr: &'static str) -> String {
- let mut output = Vec::<u8>::with_capacity(self.len());
- let mut count = 0;
- let mut last = 0;
- for i in 0..self.len() {
- let idx = i + 1;
- if self.is_char_boundary(idx) {
- if marks.contains(&count) {
- count += 1;
- last = idx;
- output.extend_from_slice(chr.as_bytes());
- continue
- }
-
- let slice: &[u8] = self[last..idx].as_bytes();
- output.extend_from_slice(slice);
-
- count += 1;
- last = idx
- }
- }
- String::from_utf8(output).expect("subst_marks failed to render String!")
- }
-}
-
-/// After whitespace
-pub trait AfterWhitespace {
- /// Given offset method will seek from there to end of string to find the first
- /// non white space. Resulting value is counted from offset.
- ///
- /// # Example
- /// ```
- /// use array_tool::string::AfterWhitespace;
- ///
- /// assert_eq!(
- /// "asdf asdf asdf".seek_end_of_whitespace(6),
- /// Some(9)
- /// );
- /// ```
- fn seek_end_of_whitespace(&self, offset: usize) -> Option<usize>;
-}
-impl AfterWhitespace for str {
- fn seek_end_of_whitespace(&self, offset: usize) -> Option<usize> {
- if self.len() < offset { return None; };
- let mut seeker = self[offset..self.len()].chars();
- let mut val = None;
- let mut indx = 0;
- while let Some(x) = seeker.next() {
- if x.ne(&" ".chars().next().unwrap()) {
- val = Some(indx);
- break;
- }
- indx += 1;
- }
- val
- }
-}
-
-/// Word wrapping
-pub trait WordWrap {
- /// White space is treated as valid content and new lines will only be swapped in for
- /// the last white space character at the end of the given width. White space may reach beyond
- /// the width you've provided. You will need to trim end of lines in your own output (e.g.
- /// splitting string at each new line and printing the line with trim_right). Or just trust
- /// that lines that are beyond the width are just white space and only print the width -
- /// ignoring tailing white space.
- ///
- /// # Example
- /// ```
- /// use array_tool::string::WordWrap;
- ///
- /// "asd asdf asd".word_wrap(8);
- /// ```
- ///
- /// # Output
- /// ```text
- /// "asd asdf\nasd"
- /// ```
- fn word_wrap(&self, width: usize) -> String;
-}
-// No need to worry about character encoding since we're only checking for the
-// space and new line characters.
-impl WordWrap for &'static str {
- fn word_wrap(&self, width: usize) -> String {
- let mut markers = vec![];
- fn wordwrap(t: &'static str, chunk: usize, offset: usize, mrkrs: &mut Vec<usize>) -> String {
- match t[offset..*vec![offset+chunk,t.len()].iter().min().unwrap()].rfind("\n") {
- None => {
- match t[offset..*vec![offset+chunk,t.len()].iter().min().unwrap()].rfind(" ") {
- Some(x) => {
- let mut eows = x; // end of white space
- if offset+chunk < t.len() { // check if white space continues
- match t.seek_end_of_whitespace(offset+x) {
- Some(a) => {
- if a.ne(&0) {
- eows = x+a-1;
- }
- },
- None => {},
- }
- }
- if offset+chunk < t.len() { // safe to seek ahead by 1 or not end of string
- if !["\n".chars().next().unwrap(), " ".chars().next().unwrap()].contains(
- &t[offset+eows+1..offset+eows+2].chars().next().unwrap()
- ) {
- mrkrs.push(offset+eows)
- }
- };
- wordwrap(t, chunk, offset+eows+1, mrkrs)
- },
- None => {
- if offset+chunk < t.len() { // String may continue
- wordwrap(t, chunk, offset+1, mrkrs) // Recurse + 1 until next space
- } else {
- use string::SubstMarks;
-
- return t.subst_marks(mrkrs.to_vec(), "\n")
- }
- },
- }
- },
- Some(x) => {
- wordwrap(t, chunk, offset+x+1, mrkrs)
- },
- }
- };
- wordwrap(self, width+1, 0, &mut markers)
- }
-}
diff --git a/vendor/array_tool/src/vec.rs b/vendor/array_tool/src/vec.rs
deleted file mode 100644
index 14c32c049..000000000
--- a/vendor/array_tool/src/vec.rs
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2015-2017 Daniel P. Clark & array_tool Developers
-//
-// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
-// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
-// http://opensource.org/licenses/MIT>, at your option. This file may not be
-// copied, modified, or distributed except according to those terms.
-
-/// Several different methods for getting, or evaluating, uniqueness.
-pub trait Uniq<T> {
- /// `uniq` returns a vector of unique values within itself as compared to
- /// the other vector which is provided as an input parameter.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Uniq;
- ///
- /// vec![1,2,3,4,5,6].uniq( vec![1,2,5,7,9] );
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![3,4,6]
- /// ```
- fn uniq(&self, other: Self) -> Self;
-
- /// `unique` removes duplicates from within the vector and returns Self.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Uniq;
- ///
- /// vec![1,2,1,3,2,3,4,5,6].unique();
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![1,2,3,4,5,6]
- /// ```
- fn unique(&self) -> Self;
-
- /// `is_unique` returns boolean value on whether all values within
- /// Self are unique.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Uniq;
- ///
- /// vec![1,2,1,3,4,3,4,5,6].is_unique();
- /// ```
- ///
- /// # Output
- /// ```text
- /// false
- /// ```
- fn is_unique(&self) -> bool;
-
- /// `uniq_via` returns a vector of unique values within itself as compared to
- /// the other vector which is provided as an input parameter, as defined by a
- /// provided custom comparator.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Uniq;
- ///
- /// vec![1,2,3,4,5,6].uniq_via( vec![1,2,5,7,9], |&l, r| l == r + 2 );
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![1,2,4,6]
- /// ```
- fn uniq_via<F: Fn(&T, &T) -> bool>(&self, other: Self, f: F) -> Self;
-
- /// `unique_via` removes duplicates, as defined by a provided custom comparator,
- /// from within the vector and returns Self.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Uniq;
- ///
- /// vec![1.0,2.0,1.4,3.3,2.1,3.5,4.6,5.2,6.2].unique_via( |l: &f64, r: &f64| l.floor() == r.floor() );
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![1.0,2.0,3.3,4.6,5.2,6.2]
- /// ```
- fn unique_via<F: Fn(&T, &T) -> bool>(&self, f: F) -> Self;
-
- /// `is_unique_via` returns boolean value on whether all values within
- /// Self are unique, as defined by a provided custom comparator.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Uniq;
- ///
- /// vec![1.0,2.0,1.4,3.3,2.1,3.5,4.6,5.2,6.2].is_unique_via( |l: &f64, r: &f64| l.floor() == r.floor() );
- /// ```
- ///
- /// # Output
- /// ```text
- /// false
- /// ```
- fn is_unique_via<F: Fn(&T, &T) -> bool>(&self, f: F) -> bool;
-}
-
-impl<T: Clone + PartialEq> Uniq<T> for Vec<T> {
- fn uniq(&self, other: Vec<T>) -> Vec<T> {
- self.uniq_via(other, |lhs, rhs| lhs == rhs)
- }
- fn unique(&self) -> Vec<T> {
- self.unique_via(|lhs, rhs| lhs == rhs)
- }
- fn is_unique(&self) -> bool {
- self.is_unique_via(|lhs, rhs| lhs == rhs)
- }
-
- fn uniq_via<F: Fn(&T, &T) -> bool>(&self, other: Vec<T>, f: F) -> Vec<T> {
- let mut out = self.unique();
- for x in other.unique() {
- for y in (0..out.len()).rev() {
- if f(&x, &out[y]) {
- out.remove(y);
- }
- }
- }
- out
- }
- fn unique_via<F: Fn(&T, &T) -> bool>(&self, f: F) -> Vec<T> {
- let mut a = self.clone();
- for x in (0..a.len()).rev() {
- for y in (x+1..a.len()).rev() {
- if f(&a[x], &a[y]) {
- a.remove(y);
- }
- }
- }
- a
- }
- fn is_unique_via<F: Fn(&T, &T) -> bool>(&self, f: F) -> bool {
- let mut a = true;
- for x in 0..self.len() {
- for y in x+1..self.len() {
- if f(&self[x], &self[y]) {
- a = false;
- break;
- }
- }
- }
- a
- }
-}
-
-/// Removes, or Adds, the first element of self.
-pub trait Shift<T> {
- /// Removes and returns the first item from the vector
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Shift;
- ///
- /// let mut x = vec![0,1,2,3];
- /// assert_eq!(x.shift(), Some(0));
- /// assert_eq!(x, vec![1,2,3]);
- /// ```
- fn shift(&mut self) -> Option<T>;
- /// Insert item at the beginning of the vector. No return value.
- ///
- /// # Example
- /// ```
- /// use array_tool::vec::Shift;
- ///
- /// let mut x = vec![1,2,3];
- /// x.unshift(0);
- /// assert_eq!(x, vec![0,1,2,3]);
- /// ```
- fn unshift(&mut self, other: T);
-}
-impl<T: PartialEq> Shift<T> for Vec<T> {
- fn shift(&mut self) -> Option<T> {
- if self.len() == 0 { return None; }
- Some(self.remove(0))
- }
- fn unshift(&mut self, other: T) {
- &self.insert(0, other);
- }
-}
-
-/// Set Intersection — Returns a new array containing elements common to the two arrays,
-/// excluding any duplicates. The order is preserved from the original array.
-pub trait Intersect<T> {
- /// # Example
- /// ```
- /// use array_tool::vec::Intersect;
- ///
- /// vec![1,1,3,5].intersect(vec![1,2,3]);
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![1,3]
- /// ```
- fn intersect(&self, Self) -> Self;
- /// # Example
- /// ```
- /// # use std::ascii::AsciiExt;
- /// use array_tool::vec::Intersect;
- ///
- /// vec!['a','a','c','e'].intersect_if(vec!['A','B','C'], |l, r| l.eq_ignore_ascii_case(r));
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec!['a','c']
- /// ```
- fn intersect_if<F: Fn(&T, &T) -> bool>(&self, Self, validator: F) -> Self;
-}
-impl<T: PartialEq + Clone> Intersect<T> for Vec<T> {
- fn intersect(&self, other: Vec<T>) -> Vec<T> {
- self.intersect_if(other, |l, r| l == r)
- }
- fn intersect_if<F: Fn(&T, &T) -> bool>(&self, other: Self, validator: F) -> Self {
- let mut out = vec![];
- let a = self.unique();
- let length = other.len();
- for x in a {
- for y in 0..length {
- if validator(&x, &other[y]) {
- out.push(x);
- break;
- }
- }
- }
- out
- }
-}
-
-/// Join vector of ToString capable things to a String with given delimiter.
-pub trait Join {
- /// # Example
- /// ```
- /// use array_tool::vec::Join;
- ///
- /// vec![1,2,3].join(",");
- /// ```
- ///
- /// # Output
- /// ```text
- /// "1,2,3"
- /// ```
- fn join(&self, joiner: &'static str) -> String;
-}
-impl<T: ToString> Join for Vec<T> {
- fn join(&self, joiner: &'static str) -> String {
- let mut out = String::from("");
- for x in 0..self.len() {
- out.push_str(&self[x].to_string());
- if x < self.len()-1 {
- out.push_str(&joiner)
- }
- }
- out
- }
-}
-
-/// Expand and duplicate the vectors content `times` the integer given
-pub trait Times {
- /// # Example
- /// ```
- /// use array_tool::vec::Times;
- ///
- /// vec![1,2,3].times(3);
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![1,2,3,1,2,3,1,2,3]
- /// ```
- fn times(&self, qty: i32) -> Self;
-}
-impl<T: Clone> Times for Vec<T> {
- fn times(&self, qty: i32) -> Vec<T> {
- if self.is_empty() { return vec![] };
- let mut out = vec![self[0].clone();self.len()*(qty as usize)];
- let mut cycle = self.iter().cycle();
- for x in 0..self.len()*(qty as usize) {
- out[x] = cycle.next().unwrap().clone();
- }
- out
- }
-}
-
-/// Create a `union` between two vectors.
-/// Returns a new vector by joining with other, excluding any duplicates and preserving
-/// the order from the original vector.
-pub trait Union {
- /// # Example
- /// ```
- /// use array_tool::vec::Union;
- ///
- /// vec!["a","b","c"].union(vec!["c","d","a"]);
- /// ```
- ///
- /// # Output
- /// ```text
- /// vec![ "a", "b", "c", "d" ]
- /// ```
- fn union(&self, other: Self) -> Self;
-}
-impl<T: PartialEq + Clone> Union for Vec<T> {
- fn union(&self, other: Vec<T>) -> Vec<T> {
- let mut stack = self.clone();
- for x in other { // don't use append method as it's destructive
- stack.push(x)
- }
- stack.unique()
- }
-}