use crate::shared::{Link, Shareable, Shared};
use std::sync::Arc;
pub struct List<T>(Vec<ListEntry<T>>);
impl<T> List<T> {
pub fn append(&mut self, o: &mut Self) {
self.0.append(&mut o.0)
}
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn clear(&mut self) {
self.0.clear()
}
pub fn dedup(&mut self)
where
T: PartialEq,
{
self.dedup_by(PartialEq::eq)
}
pub fn dedup_by<F: FnMut(&T, &T) -> bool>(&mut self, mut f: F) {
self.0.dedup_by(|r, s| f(&r.0.borrow(), &s.0.borrow()))
}
pub fn dedup_by_key<K: PartialEq, F: FnMut(&T) -> K>(&mut self, mut f: F) {
self.0.dedup_by(|r, s| f(&r.0.borrow()) == f(&s.0.borrow()))
}
pub fn drain<'a, R: std::ops::RangeBounds<usize>>(
&'a mut self,
range: R,
) -> std::iter::Map<std::vec::Drain<'a, ListEntry<T>>, fn(ListEntry<T>) -> Shared<T, super::W>>
where
T: 'static,
{
self.0.drain(range).map(|l| Shared::from_link(l.0))
}
pub fn insert(&mut self, index: usize, element: T) {
self.0.insert(index, ListEntry::new(element))
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn new() -> Self {
Self(Vec::new())
}
pub fn pop(&mut self) -> Option<Shared<T, super::W>> {
self.0.pop().map(|l| Shared::from_link(l.0))
}
pub fn push(&mut self, value: T) {
self.0.push(ListEntry::new(value))
}
pub fn remove(&mut self, index: usize) -> Shared<T, super::W> {
Shared::from_link(self.0.remove(index).0)
}
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional)
}
pub fn reserve_exact(&mut self, additional: usize) {
self.0.reserve_exact(additional)
}
pub fn resize(&mut self, new_len: usize, t: T)
where
T: Clone,
{
self.0.resize_with(new_len, || ListEntry::new(t.clone()))
}
pub fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, mut f: F) {
self.0.resize_with(new_len, || ListEntry::new(f()))
}
pub fn retain<F: FnMut(&T) -> bool>(&mut self, mut f: F) {
self.0.retain(|l| f(&l.0.borrow()))
}
pub fn retain_mut<F: FnMut(&mut ListEntry<T>) -> bool>(&mut self, f: F)
where
T: 'static,
{
self.0.retain_mut(f)
}
pub fn shrink_to(&mut self, min_capacity: usize) {
self.0.shrink_to(min_capacity)
}
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit()
}
pub fn splice<'a, R: std::ops::RangeBounds<usize>, I: 'a + IntoIterator<Item = T>>(
&'a mut self,
range: R,
replace_with: I,
) -> impl 'a + Iterator<Item = Shared<T, super::W>>
where
T: 'static,
{
self.0
.splice(range, replace_with.into_iter().map(ListEntry::new))
.map(|l| Shared::from_link(l.0))
}
pub fn split_off(&mut self, at: usize) -> Self {
Self(self.0.split_off(at))
}
pub fn swap_remove(&mut self, index: usize) -> Shared<T, super::W> {
Shared::from_link(self.0.swap_remove(index).0)
}
pub fn truncate(&mut self, len: usize) {
self.0.truncate(len)
}
pub fn try_reserve(
&mut self,
additional: usize,
) -> Result<(), std::collections::TryReserveError> {
self.0.try_reserve(additional)
}
pub fn try_reserve_exact(
&mut self,
additional: usize,
) -> Result<(), std::collections::TryReserveError> {
self.0.try_reserve_exact(additional)
}
pub fn with_capcity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity))
}
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
where
T: Ord,
{
self.binary_search_by(|l| x.cmp(l))
}
pub fn binary_search_by<F: FnMut(&T) -> std::cmp::Ordering>(
&self,
mut f: F,
) -> Result<usize, usize> {
self.0.binary_search_by(|l| f(&l.0.borrow()))
}
pub fn binary_search_by_key<B: std::cmp::Ord, F: FnMut(&T) -> B>(
&self,
b: &B,
mut f: F,
) -> Result<usize, usize> {
self.0.binary_search_by_key(b, |l| f(&l.0.borrow()))
}
pub fn contains(&self, x: &T) -> bool
where
T: PartialEq,
{
self.0.iter().any(|l| x == &*l.0.borrow())
}
pub fn ends_with(&self, needle: &[T]) -> bool
where
T: PartialEq,
{
self.0.len() >= needle.len()
&& std::iter::zip(self.0.iter().rev(), needle.iter().rev())
.all(|(l, x)| x == &*l.0.borrow())
}
pub fn fill(&mut self, t: T)
where
T: Clone,
{
self.0.fill_with(|| ListEntry::new(t.clone()))
}
pub fn fill_with<F: FnMut() -> T>(&mut self, mut f: F) {
self.0.fill_with(|| ListEntry::new(f()))
}
pub fn first(&self) -> Option<ListEntry<T>> {
self.0.first().cloned()
}
pub fn get(&self, index: usize) -> Option<ListEntry<T>> {
self.0.get(index).cloned()
}
pub unsafe fn get_unchecked(&self, index: usize) -> ListEntry<T> {
self.0.get_unchecked(index).clone()
}
pub fn iter<'a>(&'a self) -> <&'a Self as IntoIterator>::IntoIter {
self.into_iter()
}
pub fn last(&self) -> Option<ListEntry<T>> {
self.0.last().cloned()
}
pub fn partition_point<P: FnMut(&T) -> bool>(&self, mut pred: P) -> usize {
self.0.partition_point(|l| pred(&l.0.borrow()))
}
pub fn reverse(&mut self) {
self.0.reverse()
}
pub fn rotate_left(&mut self, mid: usize) {
self.0.rotate_left(mid)
}
pub fn rotate_right(&mut self, mid: usize) {
self.0.rotate_right(mid)
}
pub fn sort(&mut self)
where
T: Ord,
{
self.sort_by(Ord::cmp)
}
pub fn sort_by<F: FnMut(&T, &T) -> std::cmp::Ordering>(&mut self, mut f: F) {
self.0.sort_by(|a, b| f(&a.0.borrow(), &b.0.borrow()))
}
pub fn sort_by_cached_key<U: Ord, F: FnMut(&T) -> U>(&mut self, mut f: F) {
self.0.sort_by_cached_key(|a| f(&a.0.borrow()))
}
pub fn sort_by_key<U: Ord, F: FnMut(&T) -> U>(&mut self, mut f: F) {
self.0.sort_by_key(|a| f(&a.0.borrow()))
}
pub fn sort_unstable(&mut self)
where
T: Ord,
{
self.sort_unstable_by(Ord::cmp)
}
pub fn sort_unstable_by<F: FnMut(&T, &T) -> std::cmp::Ordering>(&mut self, mut f: F) {
self.0
.sort_unstable_by(|a, b| f(&a.0.borrow(), &b.0.borrow()))
}
pub fn sort_unstable_by_key<U: Ord, F: FnMut(&T) -> U>(&mut self, mut f: F) {
self.0.sort_unstable_by_key(|a| f(&a.0.borrow()))
}
pub fn starts_with(&self, needle: &[T]) -> bool
where
T: PartialEq,
{
self.0.len() >= needle.len()
&& std::iter::zip(&self.0, needle).all(|(l, x)| x == &*l.0.borrow())
}
pub fn swap(&mut self, a: usize, b: usize) {
self.0.swap(a, b)
}
}
impl<'a, T> IntoIterator for &'a List<T> {
type Item = ListEntry<T>;
type IntoIter = std::iter::Cloned<std::slice::Iter<'a, ListEntry<T>>>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter().cloned()
}
}
impl<T> FromIterator<T> for List<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(iter.into_iter().map(ListEntry::new).collect())
}
}
impl<T> Extend<T> for List<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.0.extend(iter.into_iter().map(ListEntry::new))
}
}
impl<'a, T: 'a + Clone> Extend<&'a T> for List<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.0.extend(iter.into_iter().cloned().map(ListEntry::new))
}
}
pub struct ListEntry<T>(Arc<Link<T>>);
impl<T> PartialEq for ListEntry<T> {
fn eq(&self, o: &Self) -> bool {
Arc::ptr_eq(&self.0, &o.0)
}
}
impl<T> Clone for ListEntry<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> ListEntry<T> {
fn new(t: T) -> Self {
ListEntry(Arc::new(Link::new(t)))
}
pub fn share_without_hook(&self) -> Shared<T, super::W> {
Shared::from_link(self.0.clone())
}
pub fn use_w<P>(&self, cx: &dioxus_core::Scope<P>) -> Shared<T, super::W> {
let mut opt = Shareable(Some(Arc::downgrade(&self.0)));
Shared::init(cx, &mut opt, || unreachable!(), super::W)
}
pub fn use_rw<P>(&self, cx: &dioxus_core::Scope<P>) -> Shared<T, super::RW> {
let mut opt = Shareable(Some(Arc::downgrade(&self.0)));
Shared::init(cx, &mut opt, || unreachable!(), super::RW)
}
}