diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/array_tool/src | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-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.rs | 166 | ||||
-rw-r--r-- | vendor/array_tool/src/lib.rs | 58 | ||||
-rw-r--r-- | vendor/array_tool/src/string.rs | 303 | ||||
-rw-r--r-- | vendor/array_tool/src/vec.rs | 318 |
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() - } -} |