2023-12-30 23:55:05 +00:00
|
|
|
use std::any::TypeId;
|
|
|
|
|
|
|
|
use super::{Reflect, util};
|
|
|
|
|
|
|
|
pub trait List: Reflect {
|
|
|
|
fn get(&self, idx: usize) -> Option<&dyn Reflect>;
|
|
|
|
fn get_mut(&mut self, idx: usize) -> Option<&mut dyn Reflect>;
|
|
|
|
|
|
|
|
/// Push a value to the end of the List. If `item` is not the same type of the list,
|
|
|
|
/// it will be returned as [`Result::Err`].
|
|
|
|
fn push_back(&mut self, item: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
|
|
|
|
fn push_front(&mut self, item: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
|
|
|
|
|
|
|
|
/// Removes an item at `idx` from the List and returns the owned value.
|
|
|
|
fn remove_at(&mut self, idx: usize) -> Option<Box<dyn Reflect>>;
|
|
|
|
|
|
|
|
/// Removes the last element from the vector and returns it, `None` if it is empty.
|
|
|
|
fn pop_back(&mut self) -> Option<Box<dyn Reflect>>;
|
|
|
|
|
|
|
|
/// Removes the first element from the vector and returns it, `None` if it is empty.
|
|
|
|
///
|
|
|
|
/// Keep in mind this is slow if the List is not a `VecDeque`, or some other list type that is
|
|
|
|
/// optimized for removing from the front.
|
|
|
|
fn pop_front(&mut self) -> Option<Box<dyn Reflect>>;
|
|
|
|
|
|
|
|
/// Append a list to this list, removing the elements from `other`.
|
|
|
|
fn append(&mut self, other: &mut dyn List);
|
|
|
|
|
|
|
|
/// Reserves at least `additional` more space in the List. The spaces are not
|
|
|
|
/// initialized to anything.
|
|
|
|
fn reserve(&mut self, additional: usize);
|
|
|
|
|
|
|
|
/// Returns the length of the list
|
|
|
|
fn len(&self) -> usize;
|
|
|
|
|
|
|
|
/// Returns the total number of elements the list can hold without reallocating.
|
|
|
|
fn capacity(&self) -> usize;
|
|
|
|
|
|
|
|
/// Returns a boolean indicating if the list is empty.
|
|
|
|
fn is_empty(&self) -> bool;
|
|
|
|
|
|
|
|
/// Returns the TypeId of the elements in the list
|
|
|
|
fn elements_id(&self) -> TypeId;
|
|
|
|
|
|
|
|
fn apply_list(&mut self, other: &dyn List);
|
|
|
|
|
|
|
|
/// Creates a new, and empty list of the same type.
|
|
|
|
fn create_empty(&self) -> Box<dyn List>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Reflect + Clone> List for Vec<T> {
|
|
|
|
fn get(&self, idx: usize) -> Option<&dyn Reflect> {
|
|
|
|
if idx < self.len() {
|
|
|
|
Some(&self[idx])
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_mut(&mut self, idx: usize) -> Option<&mut dyn Reflect> {
|
|
|
|
if idx < self.len() {
|
|
|
|
Some(&mut self[idx])
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn push_back(&mut self, item: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
|
|
|
if item.is(TypeId::of::<T>()) {
|
|
|
|
let item = *(item as Box<dyn std::any::Any>).downcast::<T>()
|
|
|
|
.unwrap();
|
|
|
|
self.push(item);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
Err(item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-06 20:52:12 +00:00
|
|
|
fn push_front(&mut self, _item: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
2023-12-30 23:55:05 +00:00
|
|
|
unimplemented!("push_front for `List` trait implementation of a `Vec<T>`. Doing so is slow!")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn remove_at(&mut self, idx: usize) -> Option<Box<dyn Reflect>> {
|
|
|
|
if idx < self.len() {
|
|
|
|
let removed = Box::new(self.remove(idx));
|
|
|
|
Some(removed)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pop_back(&mut self) -> Option<Box<dyn Reflect>> {
|
|
|
|
let popped = Box::new(self.pop());
|
|
|
|
Some(popped)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pop_front(&mut self) -> Option<Box<dyn Reflect>> {
|
|
|
|
unimplemented!("pop_front for `List` trait implementation of a `Vec<T>`. Doing so is slow!")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn append(&mut self, other: &mut dyn List) {
|
|
|
|
assert!(self.elements_id() == other.elements_id(),
|
|
|
|
"Provided a List that contains elements that don't match what's in Self!");
|
|
|
|
self.reserve(other.len());
|
|
|
|
|
|
|
|
// pop_back and reverse later is probably the best to use here. I don't have iterators
|
|
|
|
// written for `List` yet, and an implementation of pop_front for a `Vec` would be slow.
|
|
|
|
let mut other_elements = vec![];
|
|
|
|
while let Some(el) = other.pop_back() {
|
|
|
|
let el = *(el as Box<dyn std::any::Any>).downcast::<T>()
|
|
|
|
.expect("msg");
|
|
|
|
other_elements.push(el);
|
|
|
|
}
|
|
|
|
other_elements.reverse();
|
|
|
|
|
|
|
|
self.append(&mut other_elements);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn len(&self) -> usize {
|
|
|
|
self.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_empty(&self) -> bool {
|
|
|
|
self.is_empty()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn elements_id(&self) -> TypeId {
|
|
|
|
TypeId::of::<T>()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn apply_list(&mut self, other: &dyn List) {
|
|
|
|
util::apply_list(self, other);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_empty(&self) -> Box<dyn List> {
|
|
|
|
Box::new(Vec::<T>::new())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reserve(&mut self, additional: usize) {
|
|
|
|
self.reserve(additional);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn capacity(&self) -> usize {
|
|
|
|
self.capacity()
|
|
|
|
}
|
|
|
|
}
|