mirror of
https://github.com/lifegpc/pixiv_downloader.git
synced 2026-06-21 19:34:23 +08:00
171 lines
3.7 KiB
Rust
171 lines
3.7 KiB
Rust
use std::clone::Clone;
|
|
use std::cmp::PartialEq;
|
|
use std::convert::AsMut;
|
|
use std::convert::AsRef;
|
|
use std::convert::From;
|
|
use std::convert::Into;
|
|
use std::default::Default;
|
|
use std::fmt::Debug;
|
|
use std::ops::AddAssign;
|
|
use std::ops::Index;
|
|
use std::ops::IndexMut;
|
|
use std::str::FromStr;
|
|
|
|
/// A list which if index greater than count, which will return last one of the element.
|
|
pub struct NonTailList<T> {
|
|
/// The list
|
|
data: Vec<T>,
|
|
}
|
|
|
|
impl<T> AddAssign<T> for NonTailList<T> {
|
|
fn add_assign(&mut self, rhs: T) {
|
|
self.data.push(rhs)
|
|
}
|
|
}
|
|
|
|
impl<T: Clone> AddAssign<&T> for NonTailList<T> {
|
|
fn add_assign(&mut self, rhs: &T) {
|
|
self.data.push(rhs.clone())
|
|
}
|
|
}
|
|
|
|
impl<T> AsMut<NonTailList<T>> for NonTailList<T> {
|
|
fn as_mut(&mut self) -> &mut NonTailList<T> {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl<T> AsRef<NonTailList<T>> for NonTailList<T> {
|
|
fn as_ref(&self) -> &NonTailList<T> {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl<T: Clone> Clone for NonTailList<T> {
|
|
fn clone(&self) -> Self {
|
|
Self {
|
|
data: self.data.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Debug> Debug for NonTailList<T>
|
|
where
|
|
Vec<T>: Debug,
|
|
{
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
Vec::<T>::fmt(&self.data, f)
|
|
}
|
|
}
|
|
|
|
impl<T> Default for NonTailList<T> {
|
|
fn default() -> Self {
|
|
Self { data: Vec::new() }
|
|
}
|
|
}
|
|
|
|
impl<T: Clone> From<&[T]> for NonTailList<T> {
|
|
fn from(list: &[T]) -> Self {
|
|
Self {
|
|
data: Vec::from(list),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> From<Vec<T>> for NonTailList<T> {
|
|
fn from(list: Vec<T>) -> Self {
|
|
Self { data: list }
|
|
}
|
|
}
|
|
|
|
impl<T: Clone> From<&Vec<T>> for NonTailList<T> {
|
|
fn from(list: &Vec<T>) -> Self {
|
|
Self { data: list.clone() }
|
|
}
|
|
}
|
|
|
|
impl<T: FromStr> FromStr for NonTailList<T> {
|
|
type Err = T::Err;
|
|
/// Parse a list from string
|
|
/// * `s` - a list of items separated by `,`
|
|
/// # Examples
|
|
/// ```
|
|
/// let l: NonTailList<i32> = NonTailList::from_str("1,2,3").unwrap();
|
|
/// ```
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
let mut l: Vec<T> = Vec::new();
|
|
let r = s.split(",");
|
|
for i in r {
|
|
let i = i.trim();
|
|
let a = i.parse::<T>()?;
|
|
l.push(a);
|
|
}
|
|
Ok(Self { data: l })
|
|
}
|
|
}
|
|
|
|
impl<T> Into<Vec<T>> for NonTailList<T> {
|
|
fn into(self) -> Vec<T> {
|
|
self.data
|
|
}
|
|
}
|
|
|
|
impl<T: Clone> Into<Vec<T>> for &NonTailList<T> {
|
|
fn into(self) -> Vec<T> {
|
|
self.data.clone()
|
|
}
|
|
}
|
|
|
|
impl<T> Index<usize> for NonTailList<T> {
|
|
type Output = T;
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
let count = self.data.len();
|
|
if index < count {
|
|
&self.data[index]
|
|
} else {
|
|
&self.data[count - 1]
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> IndexMut<usize> for NonTailList<T> {
|
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
|
let count = self.data.len();
|
|
if index < count {
|
|
self.data.index_mut(index)
|
|
} else {
|
|
self.data.index_mut(count - 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T, V> PartialEq<Vec<V>> for NonTailList<T>
|
|
where
|
|
T: PartialEq<V>,
|
|
{
|
|
fn eq(&self, other: &Vec<V>) -> bool {
|
|
&self.data == other
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_non_tail_list() {
|
|
let mut l = NonTailList::from(vec![1, 2, 3]);
|
|
assert_eq!(1, l[0]);
|
|
assert_eq!(2, l[1]);
|
|
assert_eq!(3, l[2]);
|
|
assert_eq!(3, l[3]);
|
|
l[0] = 0;
|
|
assert_eq!(0, l[0]);
|
|
let l2: Vec<i32> = l.as_ref().into();
|
|
assert_eq!(l2, vec![0, 2, 3]);
|
|
assert_eq!(l[4], 3);
|
|
l += 4;
|
|
assert_eq!(l[3], 4);
|
|
let l = NonTailList::<i32>::from_str("1, 2, 3").unwrap();
|
|
assert!(l == vec![1, 2, 3]);
|
|
assert_eq!(l, vec![1, 2, 3]);
|
|
let l2: Vec<i32> = l.as_ref().into();
|
|
assert_eq!(l2, vec![1, 2, 3]);
|
|
}
|