1use std::rc::Rc;
2
3#[derive(Clone, Default)]
4pub enum Inner<T> {
5 #[default]
6 Nil,
7 Cons(T, List<T>, usize),
8}
9
10pub fn drop_list<T>(list: List<T>) {
17 let mut current = list;
18 loop {
19 match Rc::try_unwrap(current) {
22 Err(_) => break, Ok(inner) => {
24 match inner {
25 Inner::Nil => break,
26 Inner::Cons(_item, tail, _) => {
27 current = tail;
33 }
34 }
35 }
36 }
37 }
38}
39impl<T: PartialEq> PartialEq for Inner<T> {
40 fn eq(&self, other: &Self) -> bool {
41 match (self, other) {
42 (Self::Cons(t1, c1, l1), Self::Cons(t2, c2, l2)) => {
43 if l1 != l2 || t1 != t2 {
44 return false;
45 }
46 if Rc::ptr_eq(c1, c2) {
47 return true;
48 }
49 c1 == c2
50 }
51 (Inner::Nil, Inner::Nil) => true,
52 _ => false,
53 }
54 }
55}
56impl<T: Eq> Eq for Inner<T> {}
57impl<T: std::fmt::Debug> std::fmt::Debug for Inner<T> {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 match self {
60 Self::Nil => write!(f, "[ ]"),
61 Self::Cons(item, cons, _) => {
62 write!(f, "[ {:?}", item)?;
63 for x in cons.iter() {
64 write!(f, ", {:?}", x)?;
65 }
66 write!(f, " ]")?;
67 Ok(())
68 }
69 }
70 }
71}
72
73pub type List<T> = Rc<Inner<T>>;
74
75impl<T> Inner<T> {
76 pub fn new() -> Rc<Self> {
77 Rc::new(Inner::Nil)
78 }
79
80 pub fn len(&self) -> usize {
81 match self {
82 Inner::Nil => 0,
83 Inner::Cons(_, _, x) => *x,
84 }
85 }
86
87 pub fn prepend(self: &List<T>, value: T) -> List<T> {
88 let at = match self.as_ref() {
89 Inner::Nil => 1,
90 Inner::Cons(_, _, at) => at + 1,
91 };
92 Rc::new(Inner::Cons(value, self.clone(), at))
93 }
94
95 pub fn head(&self) -> Option<&T> {
96 match self {
97 Inner::Nil => None,
98 Inner::Cons(h, _, _) => Some(h),
99 }
100 }
101
102 pub fn tail(&self) -> Option<&List<T>> {
103 match &self {
104 Inner::Nil => None,
105 Inner::Cons(_, t, _) => Some(t),
106 }
107 }
108 pub fn slice(&self) -> Option<(&T, &List<T>)> {
109 match &self {
110 Inner::Nil => None,
111 Inner::Cons(r, t, _) => Some((r, t)),
112 }
113 }
114
115 pub fn same(self: &List<T>, other: &List<T>) -> bool {
116 Rc::ptr_eq(self, other)
117 }
118
119 pub fn iter<'a>(self: &'a List<T>) -> impl Iterator<Item = &'a T> {
120 let mut list = self;
121 std::iter::from_fn(move || match list.as_ref() {
122 Inner::Nil => None,
123 Inner::Cons(i, r, _) => {
124 list = r;
125 Some(i)
126 }
127 })
128 }
129}