1#![doc = include_str!("../README.md")]
2
3mod display;
4#[cfg(feature = "http")]
5pub mod http;
6pub mod http_server;
7#[cfg(feature = "random")]
8pub mod random;
9mod runtime;
10mod service_types;
11pub mod tcp;
12#[cfg(feature = "terminal")]
13pub mod terminal;
14
15pub use display::{AverDisplay, aver_display};
16pub use runtime::{
17 append_text, cli_args, console_error, console_print, console_warn, delete_dir, delete_file,
18 env_get, env_set, list_dir, make_dir, path_exists, read_line, read_text, string_slice,
19 time_now, time_sleep, time_unix_ms, write_text,
20};
21pub use service_types::{Header, HttpRequest, HttpResponse, TcpConnection, TerminalSize};
22
23#[cfg(feature = "terminal")]
24pub use terminal::{
25 TerminalGuard, clear as terminal_clear, disable_raw_mode as terminal_disable_raw_mode,
26 enable_raw_mode as terminal_enable_raw_mode, flush as terminal_flush,
27 hide_cursor as terminal_hide_cursor, move_to as terminal_move_to,
28 print_at_cursor as terminal_print, read_key as terminal_read_key,
29 reset_color as terminal_reset_color, restore_terminal, set_color as terminal_set_color,
30 show_cursor as terminal_show_cursor, size as terminal_size,
31};
32
33use std::collections::HashMap as StdHashMap;
34use std::fmt;
35use std::hash::{Hash, Hasher};
36use std::iter::FusedIterator;
37
38#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
40pub struct AverStr(Rc<str>);
41
42impl AverStr {
43 pub fn len(&self) -> usize {
44 self.0.len()
45 }
46 pub fn is_empty(&self) -> bool {
47 self.0.is_empty()
48 }
49}
50
51impl std::ops::Deref for AverStr {
52 type Target = str;
53 fn deref(&self) -> &str {
54 &self.0
55 }
56}
57
58impl AsRef<str> for AverStr {
59 fn as_ref(&self) -> &str {
60 &self.0
61 }
62}
63
64impl std::borrow::Borrow<str> for AverStr {
65 fn borrow(&self) -> &str {
66 &self.0
67 }
68}
69
70impl From<String> for AverStr {
71 fn from(s: String) -> Self {
72 Self(Rc::from(s.as_str()))
73 }
74}
75
76impl From<&str> for AverStr {
77 fn from(s: &str) -> Self {
78 Self(Rc::from(s))
79 }
80}
81
82impl From<Rc<str>> for AverStr {
83 fn from(s: Rc<str>) -> Self {
84 Self(s)
85 }
86}
87
88impl fmt::Display for AverStr {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 self.0.fmt(f)
91 }
92}
93
94impl fmt::Debug for AverStr {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "{:?}", &*self.0)
97 }
98}
99
100impl std::ops::Add<&AverStr> for AverStr {
101 type Output = AverStr;
102 fn add(self, other: &AverStr) -> AverStr {
103 let mut s = String::with_capacity(self.len() + other.len());
104 s.push_str(&self);
105 s.push_str(other);
106 AverStr::from(s)
107 }
108}
109
110#[inline]
112pub fn aver_str_concat(a: &AverStr, b: &AverStr) -> AverStr {
113 let mut s = String::with_capacity(a.len() + b.len());
114 s.push_str(a);
115 s.push_str(b);
116 AverStr::from(s)
117}
118use std::sync::Arc as Rc;
119
120pub fn par_execute<T: Send>(tasks: Vec<Box<dyn FnOnce() -> T + Send>>) -> Vec<T> {
125 std::thread::scope(|s| {
126 let handles: Vec<_> = tasks.into_iter().map(|task| s.spawn(task)).collect();
127 handles.into_iter().map(|h| h.join().unwrap()).collect()
128 })
129}
130
131pub type CancelTask<T, E> =
138 Box<dyn FnOnce(std::sync::Arc<std::sync::atomic::AtomicBool>) -> Result<T, E> + Send>;
139
140pub fn par_execute_with_cancel<T: Send, E: Send>(
141 tasks: Vec<CancelTask<T, E>>,
142) -> Vec<Result<T, E>> {
143 use std::sync::{Arc, atomic::AtomicBool};
144 let cancelled = Arc::new(AtomicBool::new(false));
145 std::thread::scope(|s| {
146 let handles: Vec<_> = tasks
147 .into_iter()
148 .map(|task| {
149 let flag = Arc::clone(&cancelled);
150 s.spawn(move || {
151 let result = task(Arc::clone(&flag));
152 if result.is_err() {
153 flag.store(true, std::sync::atomic::Ordering::Relaxed);
154 }
155 result
156 })
157 })
158 .collect();
159 handles.into_iter().map(|h| h.join().unwrap()).collect()
160 })
161}
162
163pub struct AverMap<K, V> {
170 inner: Rc<StdHashMap<K, V>>,
171}
172
173impl<K, V> Clone for AverMap<K, V> {
174 fn clone(&self) -> Self {
175 Self {
176 inner: Rc::clone(&self.inner),
177 }
178 }
179}
180
181impl<K, V> AverMap<K, V>
182where
183 K: Eq + Hash + Clone,
184 V: Clone,
185{
186 pub fn new() -> Self {
187 Self {
188 inner: Rc::new(StdHashMap::new()),
189 }
190 }
191
192 pub fn get(&self, key: &K) -> Option<&V> {
193 self.inner.get(key)
194 }
195
196 pub fn contains_key(&self, key: &K) -> bool {
197 self.inner.contains_key(key)
198 }
199
200 pub fn insert(&self, key: K, value: V) -> Self {
202 self.clone().insert_owned(key, value)
203 }
204
205 pub fn insert_owned(mut self, key: K, value: V) -> Self {
207 Rc::make_mut(&mut self.inner).insert(key, value);
208 self
209 }
210
211 pub fn rewrite_values_in_place(&mut self, mut f: impl FnMut(&mut V)) {
213 let inner = Rc::make_mut(&mut self.inner);
214 for value in inner.values_mut() {
215 f(value);
216 }
217 }
218
219 pub fn remove(&self, key: &K) -> Self {
221 self.clone().remove_owned(key)
222 }
223
224 pub fn remove_owned(mut self, key: &K) -> Self {
226 Rc::make_mut(&mut self.inner).remove(key);
227 self
228 }
229
230 pub fn keys(&self) -> impl Iterator<Item = &K> {
231 self.inner.keys()
232 }
233
234 pub fn values(&self) -> impl Iterator<Item = &V> {
235 self.inner.values()
236 }
237
238 pub fn len(&self) -> usize {
239 self.inner.len()
240 }
241
242 pub fn is_empty(&self) -> bool {
243 self.inner.is_empty()
244 }
245
246 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
247 self.inner.iter()
248 }
249}
250
251impl<K, V> Default for AverMap<K, V>
252where
253 K: Eq + Hash + Clone,
254 V: Clone,
255{
256 fn default() -> Self {
257 Self::new()
258 }
259}
260
261impl<K: Eq + Hash + Clone + PartialEq, V: PartialEq + Clone> PartialEq for AverMap<K, V> {
262 fn eq(&self, other: &Self) -> bool {
263 self.inner == other.inner
264 }
265}
266
267impl<K: Eq + Hash + Clone, V: Eq + Clone> Eq for AverMap<K, V> {}
268
269impl<K: Eq + Hash + Clone + Hash + Ord, V: Hash + Clone> Hash for AverMap<K, V> {
270 fn hash<H: Hasher>(&self, state: &mut H) {
271 let mut keys: Vec<&K> = self.inner.keys().collect();
273 keys.sort();
274 keys.len().hash(state);
275 for k in keys {
276 k.hash(state);
277 self.inner[k].hash(state);
278 }
279 }
280}
281
282impl<K: fmt::Debug + Eq + Hash + Clone, V: fmt::Debug + Clone> fmt::Debug for AverMap<K, V> {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 self.inner.fmt(f)
285 }
286}
287
288impl<K, V> std::ops::Index<&K> for AverMap<K, V>
289where
290 K: Eq + Hash + Clone,
291 V: Clone,
292{
293 type Output = V;
294 fn index(&self, key: &K) -> &V {
295 &self.inner[key]
296 }
297}
298
299pub struct AverVector<T> {
302 inner: Rc<Vec<T>>,
303}
304
305impl<T> Clone for AverVector<T> {
306 fn clone(&self) -> Self {
307 Self {
308 inner: Rc::clone(&self.inner),
309 }
310 }
311}
312
313impl<T: Clone> AverVector<T> {
314 pub fn new(size: usize, default: T) -> Self {
315 Self {
316 inner: Rc::new(vec![default; size]),
317 }
318 }
319
320 pub fn get(&self, index: usize) -> Option<&T> {
321 self.inner.get(index)
322 }
323
324 pub fn set_unchecked(mut self, index: usize, value: T) -> Self {
328 debug_assert!(index < self.inner.len());
329 Rc::make_mut(&mut self.inner)[index] = value;
330 self
331 }
332
333 pub fn set_owned(self, index: usize, value: T) -> Option<Self> {
335 if index >= self.inner.len() {
336 return None;
337 }
338 Some(self.set_unchecked(index, value))
339 }
340
341 pub fn set(&self, index: usize, value: T) -> Option<Self> {
343 self.clone().set_owned(index, value)
344 }
345
346 pub fn len(&self) -> usize {
347 self.inner.len()
348 }
349
350 pub fn is_empty(&self) -> bool {
351 self.inner.is_empty()
352 }
353
354 pub fn from_vec(v: Vec<T>) -> Self {
355 Self { inner: Rc::new(v) }
356 }
357
358 pub fn to_vec(&self) -> Vec<T> {
359 self.inner.as_ref().clone()
360 }
361
362 pub fn to_list(&self) -> AverList<T> {
364 AverList::from_rc_vec(Rc::clone(&self.inner))
365 }
366
367 pub fn from_list(list: &AverList<T>) -> Self
369 where
370 T: Clone,
371 {
372 Self {
373 inner: list.into_rc_vec(),
374 }
375 }
376
377 pub fn iter(&self) -> std::slice::Iter<'_, T> {
378 self.inner.iter()
379 }
380}
381
382impl<T: PartialEq> PartialEq for AverVector<T> {
383 fn eq(&self, other: &Self) -> bool {
384 self.inner == other.inner
385 }
386}
387
388impl<T: Eq> Eq for AverVector<T> {}
389
390impl<T: Hash> Hash for AverVector<T> {
391 fn hash<H: Hasher>(&self, state: &mut H) {
392 9u8.hash(state);
393 self.inner.hash(state);
394 }
395}
396
397impl<T: fmt::Debug> fmt::Debug for AverVector<T> {
398 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
399 write!(f, "Vector")?;
400 f.debug_list().entries(self.inner.iter()).finish()
401 }
402}
403
404const LIST_APPEND_CHUNK_LIMIT: usize = 128;
407
408pub struct AverList<T> {
409 inner: Rc<AverListInner<T>>,
410}
411
412enum AverListInner<T> {
413 Flat {
414 items: Rc<Vec<T>>,
415 start: usize,
416 },
417 Prepend {
418 head: T,
419 tail: AverList<T>,
420 len: usize,
421 },
422 Concat {
423 left: AverList<T>,
424 right: AverList<T>,
425 len: usize,
426 },
427 Segments {
428 current: AverList<T>,
429 rest: Rc<Vec<AverList<T>>>,
430 start: usize,
431 len: usize,
432 },
433}
434
435fn empty_list_inner<T>() -> Rc<AverListInner<T>> {
436 Rc::new(AverListInner::Flat {
437 items: Rc::new(Vec::new()),
438 start: 0,
439 })
440}
441
442fn empty_list<T>(inner: &Rc<AverListInner<T>>) -> AverList<T> {
443 AverList {
444 inner: Rc::clone(inner),
445 }
446}
447
448fn take_list_inner<T>(
449 list: &mut AverList<T>,
450 empty_inner: &Rc<AverListInner<T>>,
451) -> Rc<AverListInner<T>> {
452 let original = std::mem::replace(list, empty_list(empty_inner));
453 original.inner
454}
455
456fn detach_unique_children<T>(
457 inner: &mut AverListInner<T>,
458 empty_inner: &Rc<AverListInner<T>>,
459 pending: &mut Vec<Rc<AverListInner<T>>>,
460) {
461 match inner {
462 AverListInner::Flat { .. } => {}
463 AverListInner::Prepend { tail, .. } => {
464 pending.push(take_list_inner(tail, empty_inner));
465 }
466 AverListInner::Concat { left, right, .. } => {
467 pending.push(take_list_inner(left, empty_inner));
468 pending.push(take_list_inner(right, empty_inner));
469 }
470 AverListInner::Segments { current, rest, .. } => {
471 pending.push(take_list_inner(current, empty_inner));
472 let rest_rc = std::mem::replace(rest, Rc::new(Vec::new()));
473 if let Ok(mut rest_vec) = Rc::try_unwrap(rest_rc) {
474 for part in &mut rest_vec {
475 pending.push(take_list_inner(part, empty_inner));
476 }
477 }
478 }
479 }
480}
481
482impl<T> Drop for AverListInner<T> {
483 fn drop(&mut self) {
484 if matches!(self, AverListInner::Flat { .. }) {
485 return;
486 }
487
488 let empty_inner = empty_list_inner();
489 let mut pending = Vec::new();
490
491 detach_unique_children(self, &empty_inner, &mut pending);
494
495 while let Some(child) = pending.pop() {
496 if let Ok(mut child_inner) = Rc::try_unwrap(child) {
497 detach_unique_children(&mut child_inner, &empty_inner, &mut pending);
498 }
499 }
500 }
501}
502
503#[derive(Clone)]
504enum ListCursor<'a, T> {
505 Node(&'a AverList<T>),
506 Slice(&'a [T], usize),
507 SegmentSlice(&'a [AverList<T>], usize),
508}
509
510pub struct AverListIter<'a, T> {
511 stack: Vec<ListCursor<'a, T>>,
512 remaining: usize,
513}
514
515impl<T> Clone for AverList<T> {
516 fn clone(&self) -> Self {
517 Self {
518 inner: Rc::clone(&self.inner),
519 }
520 }
521}
522
523impl<T> AverList<T> {
524 fn concat_node(left: &Self, right: &Self) -> Self {
525 Self {
526 inner: Rc::new(AverListInner::Concat {
527 left: left.clone(),
528 right: right.clone(),
529 len: left.len() + right.len(),
530 }),
531 }
532 }
533
534 fn segments_rc(mut current: Self, rest: Rc<Vec<Self>>, mut start: usize) -> Self {
535 while current.is_empty() {
536 if let Some(next) = rest.get(start).cloned() {
537 current = next;
538 start += 1;
539 } else {
540 return Self::empty();
541 }
542 }
543
544 if start >= rest.len() {
545 return current;
546 }
547
548 let len = current.len() + rest[start..].iter().map(AverList::len).sum::<usize>();
549 Self {
550 inner: Rc::new(AverListInner::Segments {
551 current,
552 rest,
553 start,
554 len,
555 }),
556 }
557 }
558
559 fn rebuild_from_rights(mut base: Self, mut rights: Vec<Self>) -> Self {
560 while let Some(right) = rights.pop() {
561 base = Self::concat(&base, &right);
562 }
563 base
564 }
565
566 fn flat_tail(items: &Rc<Vec<T>>, start: usize) -> Option<Self> {
567 if start >= items.len() {
568 return None;
569 }
570 if start + 1 >= items.len() {
571 return Some(Self::empty());
572 }
573 Some(Self {
574 inner: Rc::new(AverListInner::Flat {
575 items: Rc::clone(items),
576 start: start + 1,
577 }),
578 })
579 }
580
581 fn uncons(&self) -> Option<(&T, Self)> {
582 let mut rights = Vec::new();
583 let mut current = self;
584
585 loop {
586 match current.inner.as_ref() {
587 AverListInner::Flat { items, start } => {
588 let head = items.get(*start)?;
589 let tail = Self::flat_tail(items, *start)?;
590 return Some((head, Self::rebuild_from_rights(tail, rights)));
591 }
592 AverListInner::Prepend { head, tail, .. } => {
593 return Some((head, Self::rebuild_from_rights(tail.clone(), rights)));
594 }
595 AverListInner::Concat { left, right, .. } => {
596 if left.is_empty() {
597 current = right;
598 continue;
599 }
600 rights.push(right.clone());
601 current = left;
602 }
603 AverListInner::Segments {
604 current: head_segment,
605 rest,
606 start,
607 ..
608 } => {
609 let (head, tail) = head_segment.uncons()?;
610 return Some((head, Self::segments_rc(tail, Rc::clone(rest), *start)));
611 }
612 }
613 }
614 }
615
616 pub fn uncons_cloned(&self) -> Option<(T, Self)>
617 where
618 T: Clone,
619 {
620 self.uncons().map(|(head, tail)| (head.clone(), tail))
621 }
622
623 pub fn empty() -> Self {
624 Self::from_vec(vec![])
625 }
626
627 pub fn from_vec(items: Vec<T>) -> Self {
628 Self {
629 inner: Rc::new(AverListInner::Flat {
630 items: Rc::new(items),
631 start: 0,
632 }),
633 }
634 }
635
636 pub fn from_rc_vec(items: Rc<Vec<T>>) -> Self {
638 Self {
639 inner: Rc::new(AverListInner::Flat { items, start: 0 }),
640 }
641 }
642
643 pub fn into_rc_vec(&self) -> Rc<Vec<T>>
645 where
646 T: Clone,
647 {
648 match self.inner.as_ref() {
649 AverListInner::Flat { items, start } if *start == 0 => Rc::clone(items),
650 _ => Rc::new(self.to_vec()),
651 }
652 }
653
654 pub fn len(&self) -> usize {
655 match self.inner.as_ref() {
656 AverListInner::Flat { items, start } => items.len().saturating_sub(*start),
657 AverListInner::Prepend { len, .. }
658 | AverListInner::Concat { len, .. }
659 | AverListInner::Segments { len, .. } => *len,
660 }
661 }
662
663 pub fn is_empty(&self) -> bool {
664 self.len() == 0
665 }
666
667 pub fn get(&self, index: usize) -> Option<&T> {
668 let mut current = self;
669 let mut remaining = index;
670
671 loop {
672 match current.inner.as_ref() {
673 AverListInner::Flat { items, start } => {
674 return items.get(start.saturating_add(remaining));
675 }
676 AverListInner::Prepend { head, tail, .. } => {
677 if remaining == 0 {
678 return Some(head);
679 }
680 remaining -= 1;
681 current = tail;
682 }
683 AverListInner::Concat { left, right, .. } => {
684 let left_len = left.len();
685 if remaining < left_len {
686 current = left;
687 } else {
688 remaining -= left_len;
689 current = right;
690 }
691 }
692 AverListInner::Segments {
693 current: head_segment,
694 rest,
695 start,
696 ..
697 } => {
698 let head_len = head_segment.len();
699 if remaining < head_len {
700 current = head_segment;
701 } else {
702 remaining -= head_len;
703 let mut found = None;
704 for part in &rest[*start..] {
705 let part_len = part.len();
706 if remaining < part_len {
707 found = Some(part);
708 break;
709 }
710 remaining -= part_len;
711 }
712 current = found?;
713 }
714 }
715 }
716 }
717 }
718
719 pub fn first(&self) -> Option<&T> {
720 self.get(0)
721 }
722
723 pub fn as_slice(&self) -> Option<&[T]> {
724 match self.inner.as_ref() {
725 AverListInner::Flat { items, start } => Some(items.get(*start..).unwrap_or(&[])),
726 AverListInner::Prepend { .. }
727 | AverListInner::Concat { .. }
728 | AverListInner::Segments { .. } => None,
729 }
730 }
731
732 pub fn iter(&self) -> AverListIter<'_, T> {
733 AverListIter {
734 stack: vec![ListCursor::Node(self)],
735 remaining: self.len(),
736 }
737 }
738
739 pub fn tail(&self) -> Option<Self> {
740 match self.inner.as_ref() {
741 AverListInner::Flat { items, start } => Self::flat_tail(items, *start),
742 AverListInner::Prepend { tail, .. } => Some(tail.clone()),
743 AverListInner::Concat { .. } | AverListInner::Segments { .. } => {
744 self.uncons().map(|(_, tail)| tail)
745 }
746 }
747 }
748
749 pub fn prepend(item: T, list: &Self) -> Self {
750 if list.is_empty() {
751 return Self::from_vec(vec![item]);
752 }
753 Self {
754 inner: Rc::new(AverListInner::Prepend {
755 head: item,
756 tail: list.clone(),
757 len: list.len() + 1,
758 }),
759 }
760 }
761
762 pub fn concat(left: &Self, right: &Self) -> Self {
763 if left.is_empty() {
764 return right.clone();
765 }
766 if right.is_empty() {
767 return left.clone();
768 }
769 Self::concat_node(left, right)
770 }
771
772 pub fn append(list: &Self, item: T) -> Self {
773 let singleton = Self::from_vec(vec![item]);
774 if list.is_empty() {
775 return singleton;
776 }
777
778 match list.inner.as_ref() {
779 AverListInner::Segments {
780 current,
781 rest,
782 start,
783 ..
784 } => {
785 let mut parts = rest[*start..].to_vec();
786 if let Some(last) = parts.last_mut() {
787 if last.len() < LIST_APPEND_CHUNK_LIMIT {
788 *last = Self::concat(last, &singleton);
789 } else {
790 parts.push(singleton);
791 }
792 } else {
793 parts.push(singleton);
794 }
795 Self::segments_rc(current.clone(), Rc::new(parts), 0)
796 }
797 _ if list.len() < LIST_APPEND_CHUNK_LIMIT => Self::concat(list, &singleton),
798 _ => Self::segments_rc(list.clone(), Rc::new(vec![singleton]), 0),
799 }
800 }
801
802 pub fn to_vec(&self) -> Vec<T>
803 where
804 T: Clone,
805 {
806 let mut out = Vec::with_capacity(self.len());
807 out.extend(self.iter().cloned());
808 out
809 }
810
811 pub fn reverse(&self) -> Self
812 where
813 T: Clone,
814 {
815 let mut out = self.to_vec();
816 out.reverse();
817 Self::from_vec(out)
818 }
819
820 pub fn contains(&self, item: &T) -> bool
821 where
822 T: PartialEq,
823 {
824 self.iter().any(|x| x == item)
825 }
826}
827
828impl<'a, T> Iterator for AverListIter<'a, T> {
829 type Item = &'a T;
830
831 fn next(&mut self) -> Option<Self::Item> {
832 while let Some(cursor) = self.stack.pop() {
833 match cursor {
834 ListCursor::Slice(items, index) => {
835 if let Some(item) = items.get(index) {
836 self.stack.push(ListCursor::Slice(items, index + 1));
837 self.remaining = self.remaining.saturating_sub(1);
838 return Some(item);
839 }
840 }
841 ListCursor::Node(list) => match list.inner.as_ref() {
842 AverListInner::Flat { items, start } => {
843 let slice = items.get(*start..).unwrap_or(&[]);
844 if !slice.is_empty() {
845 self.stack.push(ListCursor::Slice(slice, 0));
846 }
847 }
848 AverListInner::Prepend { head, tail, .. } => {
849 self.stack.push(ListCursor::Node(tail));
850 self.remaining = self.remaining.saturating_sub(1);
851 return Some(head);
852 }
853 AverListInner::Concat { left, right, .. } => {
854 self.stack.push(ListCursor::Node(right));
855 self.stack.push(ListCursor::Node(left));
856 }
857 AverListInner::Segments {
858 current,
859 rest,
860 start,
861 ..
862 } => {
863 let slice = rest.get(*start..).unwrap_or(&[]);
864 if !slice.is_empty() {
865 self.stack.push(ListCursor::SegmentSlice(slice, 0));
866 }
867 self.stack.push(ListCursor::Node(current));
868 }
869 },
870 ListCursor::SegmentSlice(items, index) => {
871 if let Some(item) = items.get(index) {
872 self.stack.push(ListCursor::SegmentSlice(items, index + 1));
873 self.stack.push(ListCursor::Node(item));
874 }
875 }
876 }
877 }
878 None
879 }
880
881 fn size_hint(&self) -> (usize, Option<usize>) {
882 (self.remaining, Some(self.remaining))
883 }
884}
885
886impl<T> ExactSizeIterator for AverListIter<'_, T> {
887 fn len(&self) -> usize {
888 self.remaining
889 }
890}
891
892impl<T> FusedIterator for AverListIter<'_, T> {}
893
894impl<'a, T> IntoIterator for &'a AverList<T> {
895 type Item = &'a T;
896 type IntoIter = AverListIter<'a, T>;
897
898 fn into_iter(self) -> Self::IntoIter {
899 self.iter()
900 }
901}
902
903impl<T: Clone> IntoIterator for AverList<T> {
904 type Item = T;
905 type IntoIter = std::vec::IntoIter<T>;
906
907 fn into_iter(self) -> Self::IntoIter {
908 self.to_vec().into_iter()
909 }
910}
911
912impl<T: fmt::Debug> fmt::Debug for AverList<T> {
913 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
914 f.debug_list().entries(self.iter()).finish()
915 }
916}
917
918impl<T: PartialEq> PartialEq for AverList<T> {
919 fn eq(&self, other: &Self) -> bool {
920 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a == b)
921 }
922}
923
924impl<T: Eq> Eq for AverList<T> {}
925
926impl<T: Hash> Hash for AverList<T> {
927 fn hash<H: Hasher>(&self, state: &mut H) {
928 8u8.hash(state);
929 self.len().hash(state);
930 for item in self.iter() {
931 item.hash(state);
932 }
933 }
934}
935
936pub fn list_uncons<T>(list: &AverList<T>) -> Option<(&T, AverList<T>)> {
937 list.uncons()
938}
939
940pub fn list_uncons_cloned<T: Clone>(list: &AverList<T>) -> Option<(T, AverList<T>)> {
941 list.uncons_cloned()
942}
943
944#[macro_export]
946macro_rules! aver_list_match {
947 ($list:expr, [] => $empty:expr, [$head:ident, $tail:ident] => $cons:expr) => {{
948 let __aver_list = $list;
949 if __aver_list.is_empty() {
950 $empty
951 } else if let ::core::option::Option::Some(($head, $tail)) =
952 $crate::list_uncons_cloned(&__aver_list)
953 {
954 $cons
955 } else {
956 panic!("Aver: non-exhaustive list match")
957 }
958 }};
959}
960
961pub fn string_join<S: AsRef<str>>(parts: &AverList<S>, sep: &str) -> String {
962 let mut iter = parts.iter();
963 let Some(first) = iter.next() else {
964 return String::new();
965 };
966 let mut out = first.as_ref().to_string();
967 for part in iter {
968 out.push_str(sep);
969 out.push_str(part.as_ref());
970 }
971 out
972}
973
974#[cfg(test)]
975mod tests {
976 use super::{
977 AverList, AverListInner, LIST_APPEND_CHUNK_LIMIT, aver_display, env_set, string_slice,
978 };
979
980 #[test]
981 fn prepend_and_tail_share_structure() {
982 let base = AverList::from_vec(vec![2, 3]);
983 let full = AverList::prepend(1, &base);
984 assert_eq!(full.first(), Some(&1));
985 assert_eq!(full.tail().unwrap(), base);
986 }
987
988 #[test]
989 fn concat_and_iter_preserve_order() {
990 let left = AverList::from_vec(vec![1, 2]);
991 let right = AverList::from_vec(vec![3, 4]);
992 let joined = AverList::concat(&left, &right);
993 assert_eq!(joined.to_vec(), vec![1, 2, 3, 4]);
994 }
995
996 #[test]
997 fn dropping_deep_prepend_chain_does_not_overflow() {
998 let mut list = AverList::empty();
999 for value in 0..200_000 {
1000 list = AverList::prepend(value, &list);
1001 }
1002
1003 assert_eq!(list.len(), 200_000);
1004 drop(list);
1005 }
1006
1007 #[test]
1008 fn tail_of_deep_append_chain_does_not_overflow() {
1009 let mut list = AverList::empty();
1010 for value in 0..200_000 {
1011 list = AverList::append(&list, value);
1012 }
1013
1014 let tail = list.tail().expect("non-empty list must have a tail");
1015 assert_eq!(tail.len(), 199_999);
1016 assert_eq!(tail.first(), Some(&1));
1017 }
1018
1019 #[test]
1020 fn list_uncons_of_deep_append_chain_does_not_overflow() {
1021 let mut list = AverList::empty();
1022 for value in 0..200_000 {
1023 list = AverList::append(&list, value);
1024 }
1025
1026 let (head, tail) = super::list_uncons(&list).expect("non-empty list must uncons");
1027 assert_eq!(*head, 0);
1028 assert_eq!(tail.len(), 199_999);
1029 assert_eq!(tail.first(), Some(&1));
1030 }
1031
1032 #[test]
1033 fn cloned_uncons_preserves_append_chain_tail_contents() {
1034 let mut list = AverList::empty();
1035 for value in 0..5 {
1036 list = AverList::append(&list, value);
1037 }
1038
1039 let (head, tail) = super::list_uncons_cloned(&list).expect("non-empty list must uncons");
1040 assert_eq!(head, 0);
1041 assert_eq!(tail.to_vec(), vec![1, 2, 3, 4]);
1042 }
1043
1044 #[test]
1045 fn get_reads_flat_list_in_place() {
1046 let list = AverList::from_vec(vec![10, 20, 30]);
1047
1048 assert_eq!(list.get(0), Some(&10));
1049 assert_eq!(list.get(2), Some(&30));
1050 assert_eq!(list.get(3), None);
1051 }
1052
1053 #[test]
1054 fn get_walks_concat_and_prepend_without_flattening() {
1055 let base = AverList::from_vec(vec![2, 3]);
1056 let prepended = AverList::prepend(1, &base);
1057 let joined = AverList::concat(&prepended, &AverList::from_vec(vec![4, 5]));
1058
1059 assert_eq!(joined.get(0), Some(&1));
1060 assert_eq!(joined.get(2), Some(&3));
1061 assert_eq!(joined.get(4), Some(&5));
1062 assert_eq!(joined.get(5), None);
1063 }
1064
1065 #[test]
1066 fn repeated_tail_over_append_chain_preserves_all_items() {
1067 let mut list = AverList::empty();
1068 for value in 0..6 {
1069 list = AverList::append(&list, value);
1070 }
1071
1072 let mut rest = list;
1073 let mut seen = Vec::new();
1074 while let Some((head, tail)) = super::list_uncons(&rest) {
1075 seen.push(*head);
1076 rest = tail;
1077 }
1078
1079 assert_eq!(seen, vec![0, 1, 2, 3, 4, 5]);
1080 }
1081
1082 #[test]
1083 fn append_promotes_long_right_spines_into_segments() {
1084 let mut list = AverList::empty();
1085 for value in 0..200 {
1086 list = AverList::append(&list, value);
1087 }
1088
1089 match list.inner.as_ref() {
1090 AverListInner::Segments {
1091 current,
1092 rest,
1093 start,
1094 ..
1095 } => {
1096 assert_eq!(current.len(), LIST_APPEND_CHUNK_LIMIT);
1097 assert_eq!(rest[*start].len(), 72);
1098 }
1099 other => panic!(
1100 "expected segmented append shape, got {}",
1101 aver_display_shape(other)
1102 ),
1103 }
1104 }
1105
1106 #[test]
1107 fn get_walks_segmented_append_chain_without_losing_order() {
1108 let mut list = AverList::empty();
1109 for value in 0..300 {
1110 list = AverList::append(&list, value);
1111 }
1112
1113 assert_eq!(list.get(0), Some(&0));
1114 assert_eq!(list.get(127), Some(&127));
1115 assert_eq!(list.get(128), Some(&128));
1116 assert_eq!(list.get(255), Some(&255));
1117 assert_eq!(list.get(299), Some(&299));
1118 assert_eq!(list.get(300), None);
1119 }
1120
1121 #[test]
1122 fn aver_display_quotes_strings_inside_lists() {
1123 let parts = AverList::from_vec(vec!["a".to_string(), "b".to_string()]);
1124 assert_eq!(aver_display(&parts), "[\"a\", \"b\"]");
1125 }
1126
1127 #[test]
1128 fn string_slice_uses_code_point_indices() {
1129 assert_eq!(string_slice("zażółć", 1, 4), "ażó");
1130 }
1131
1132 #[test]
1133 fn string_slice_clamps_negative_indices() {
1134 assert_eq!(string_slice("hello", -2, 2), "he");
1135 assert_eq!(string_slice("hello", 1, -1), "");
1136 }
1137
1138 #[test]
1139 fn env_set_rejects_invalid_keys() {
1140 assert_eq!(
1141 env_set("", "x"),
1142 Err("Env.set: key must not be empty".to_string())
1143 );
1144 assert_eq!(
1145 env_set("A=B", "x"),
1146 Err("Env.set: key must not contain '='".to_string())
1147 );
1148 }
1149
1150 fn aver_display_shape<T>(inner: &AverListInner<T>) -> &'static str {
1151 match inner {
1152 AverListInner::Flat { .. } => "Flat",
1153 AverListInner::Prepend { .. } => "Prepend",
1154 AverListInner::Concat { .. } => "Concat",
1155 AverListInner::Segments { .. } => "Segments",
1156 }
1157 }
1158}