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 remove(&self, key: &K) -> Self {
213 self.clone().remove_owned(key)
214 }
215
216 pub fn remove_owned(mut self, key: &K) -> Self {
218 Rc::make_mut(&mut self.inner).remove(key);
219 self
220 }
221
222 pub fn keys(&self) -> impl Iterator<Item = &K> {
223 self.inner.keys()
224 }
225
226 pub fn values(&self) -> impl Iterator<Item = &V> {
227 self.inner.values()
228 }
229
230 pub fn len(&self) -> usize {
231 self.inner.len()
232 }
233
234 pub fn is_empty(&self) -> bool {
235 self.inner.is_empty()
236 }
237
238 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
239 self.inner.iter()
240 }
241}
242
243impl<K, V> Default for AverMap<K, V>
244where
245 K: Eq + Hash + Clone,
246 V: Clone,
247{
248 fn default() -> Self {
249 Self::new()
250 }
251}
252
253impl<K: Eq + Hash + Clone + PartialEq, V: PartialEq + Clone> PartialEq for AverMap<K, V> {
254 fn eq(&self, other: &Self) -> bool {
255 self.inner == other.inner
256 }
257}
258
259impl<K: Eq + Hash + Clone, V: Eq + Clone> Eq for AverMap<K, V> {}
260
261impl<K: Eq + Hash + Clone + Hash + Ord, V: Hash + Clone> Hash for AverMap<K, V> {
262 fn hash<H: Hasher>(&self, state: &mut H) {
263 let mut keys: Vec<&K> = self.inner.keys().collect();
265 keys.sort();
266 keys.len().hash(state);
267 for k in keys {
268 k.hash(state);
269 self.inner[k].hash(state);
270 }
271 }
272}
273
274impl<K: fmt::Debug + Eq + Hash + Clone, V: fmt::Debug + Clone> fmt::Debug for AverMap<K, V> {
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 self.inner.fmt(f)
277 }
278}
279
280impl<K, V> std::ops::Index<&K> for AverMap<K, V>
281where
282 K: Eq + Hash + Clone,
283 V: Clone,
284{
285 type Output = V;
286 fn index(&self, key: &K) -> &V {
287 &self.inner[key]
288 }
289}
290
291pub struct AverVector<T> {
294 inner: Rc<Vec<T>>,
295}
296
297impl<T> Clone for AverVector<T> {
298 fn clone(&self) -> Self {
299 Self {
300 inner: Rc::clone(&self.inner),
301 }
302 }
303}
304
305impl<T: Clone> AverVector<T> {
306 pub fn new(size: usize, default: T) -> Self {
307 Self {
308 inner: Rc::new(vec![default; size]),
309 }
310 }
311
312 pub fn get(&self, index: usize) -> Option<&T> {
313 self.inner.get(index)
314 }
315
316 pub fn set_unchecked(mut self, index: usize, value: T) -> Self {
320 debug_assert!(index < self.inner.len());
321 Rc::make_mut(&mut self.inner)[index] = value;
322 self
323 }
324
325 pub fn set_owned(self, index: usize, value: T) -> Option<Self> {
327 if index >= self.inner.len() {
328 return None;
329 }
330 Some(self.set_unchecked(index, value))
331 }
332
333 pub fn set(&self, index: usize, value: T) -> Option<Self> {
335 self.clone().set_owned(index, value)
336 }
337
338 pub fn len(&self) -> usize {
339 self.inner.len()
340 }
341
342 pub fn is_empty(&self) -> bool {
343 self.inner.is_empty()
344 }
345
346 pub fn from_vec(v: Vec<T>) -> Self {
347 Self { inner: Rc::new(v) }
348 }
349
350 pub fn to_vec(&self) -> Vec<T> {
351 self.inner.as_ref().clone()
352 }
353
354 pub fn to_list(&self) -> AverList<T> {
356 AverList::from_rc_vec(Rc::clone(&self.inner))
357 }
358
359 pub fn from_list(list: &AverList<T>) -> Self
361 where
362 T: Clone,
363 {
364 Self {
365 inner: list.into_rc_vec(),
366 }
367 }
368
369 pub fn iter(&self) -> std::slice::Iter<'_, T> {
370 self.inner.iter()
371 }
372}
373
374impl<T: PartialEq> PartialEq for AverVector<T> {
375 fn eq(&self, other: &Self) -> bool {
376 self.inner == other.inner
377 }
378}
379
380impl<T: Eq> Eq for AverVector<T> {}
381
382impl<T: Hash> Hash for AverVector<T> {
383 fn hash<H: Hasher>(&self, state: &mut H) {
384 9u8.hash(state);
385 self.inner.hash(state);
386 }
387}
388
389impl<T: fmt::Debug> fmt::Debug for AverVector<T> {
390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391 write!(f, "Vector")?;
392 f.debug_list().entries(self.inner.iter()).finish()
393 }
394}
395
396const LIST_APPEND_CHUNK_LIMIT: usize = 128;
399
400pub struct AverList<T> {
401 inner: Rc<AverListInner<T>>,
402}
403
404enum AverListInner<T> {
405 Flat {
406 items: Rc<Vec<T>>,
407 start: usize,
408 },
409 Prepend {
410 head: T,
411 tail: AverList<T>,
412 len: usize,
413 },
414 Concat {
415 left: AverList<T>,
416 right: AverList<T>,
417 len: usize,
418 },
419 Segments {
420 current: AverList<T>,
421 rest: Rc<Vec<AverList<T>>>,
422 start: usize,
423 len: usize,
424 },
425}
426
427fn empty_list_inner<T>() -> Rc<AverListInner<T>> {
428 Rc::new(AverListInner::Flat {
429 items: Rc::new(Vec::new()),
430 start: 0,
431 })
432}
433
434fn empty_list<T>(inner: &Rc<AverListInner<T>>) -> AverList<T> {
435 AverList {
436 inner: Rc::clone(inner),
437 }
438}
439
440fn take_list_inner<T>(
441 list: &mut AverList<T>,
442 empty_inner: &Rc<AverListInner<T>>,
443) -> Rc<AverListInner<T>> {
444 let original = std::mem::replace(list, empty_list(empty_inner));
445 original.inner
446}
447
448fn detach_unique_children<T>(
449 inner: &mut AverListInner<T>,
450 empty_inner: &Rc<AverListInner<T>>,
451 pending: &mut Vec<Rc<AverListInner<T>>>,
452) {
453 match inner {
454 AverListInner::Flat { .. } => {}
455 AverListInner::Prepend { tail, .. } => {
456 pending.push(take_list_inner(tail, empty_inner));
457 }
458 AverListInner::Concat { left, right, .. } => {
459 pending.push(take_list_inner(left, empty_inner));
460 pending.push(take_list_inner(right, empty_inner));
461 }
462 AverListInner::Segments { current, rest, .. } => {
463 pending.push(take_list_inner(current, empty_inner));
464 let rest_rc = std::mem::replace(rest, Rc::new(Vec::new()));
465 if let Ok(mut rest_vec) = Rc::try_unwrap(rest_rc) {
466 for part in &mut rest_vec {
467 pending.push(take_list_inner(part, empty_inner));
468 }
469 }
470 }
471 }
472}
473
474impl<T> Drop for AverListInner<T> {
475 fn drop(&mut self) {
476 if matches!(self, AverListInner::Flat { .. }) {
477 return;
478 }
479
480 let empty_inner = empty_list_inner();
481 let mut pending = Vec::new();
482
483 detach_unique_children(self, &empty_inner, &mut pending);
486
487 while let Some(child) = pending.pop() {
488 if let Ok(mut child_inner) = Rc::try_unwrap(child) {
489 detach_unique_children(&mut child_inner, &empty_inner, &mut pending);
490 }
491 }
492 }
493}
494
495#[derive(Clone)]
496enum ListCursor<'a, T> {
497 Node(&'a AverList<T>),
498 Slice(&'a [T], usize),
499 SegmentSlice(&'a [AverList<T>], usize),
500}
501
502pub struct AverListIter<'a, T> {
503 stack: Vec<ListCursor<'a, T>>,
504 remaining: usize,
505}
506
507impl<T> Clone for AverList<T> {
508 fn clone(&self) -> Self {
509 Self {
510 inner: Rc::clone(&self.inner),
511 }
512 }
513}
514
515impl<T> AverList<T> {
516 fn concat_node(left: &Self, right: &Self) -> Self {
517 Self {
518 inner: Rc::new(AverListInner::Concat {
519 left: left.clone(),
520 right: right.clone(),
521 len: left.len() + right.len(),
522 }),
523 }
524 }
525
526 fn segments_rc(mut current: Self, rest: Rc<Vec<Self>>, mut start: usize) -> Self {
527 while current.is_empty() {
528 if let Some(next) = rest.get(start).cloned() {
529 current = next;
530 start += 1;
531 } else {
532 return Self::empty();
533 }
534 }
535
536 if start >= rest.len() {
537 return current;
538 }
539
540 let len = current.len() + rest[start..].iter().map(AverList::len).sum::<usize>();
541 Self {
542 inner: Rc::new(AverListInner::Segments {
543 current,
544 rest,
545 start,
546 len,
547 }),
548 }
549 }
550
551 fn rebuild_from_rights(mut base: Self, mut rights: Vec<Self>) -> Self {
552 while let Some(right) = rights.pop() {
553 base = Self::concat(&base, &right);
554 }
555 base
556 }
557
558 fn flat_tail(items: &Rc<Vec<T>>, start: usize) -> Option<Self> {
559 if start >= items.len() {
560 return None;
561 }
562 if start + 1 >= items.len() {
563 return Some(Self::empty());
564 }
565 Some(Self {
566 inner: Rc::new(AverListInner::Flat {
567 items: Rc::clone(items),
568 start: start + 1,
569 }),
570 })
571 }
572
573 fn uncons(&self) -> Option<(&T, Self)> {
574 let mut rights = Vec::new();
575 let mut current = self;
576
577 loop {
578 match current.inner.as_ref() {
579 AverListInner::Flat { items, start } => {
580 let head = items.get(*start)?;
581 let tail = Self::flat_tail(items, *start)?;
582 return Some((head, Self::rebuild_from_rights(tail, rights)));
583 }
584 AverListInner::Prepend { head, tail, .. } => {
585 return Some((head, Self::rebuild_from_rights(tail.clone(), rights)));
586 }
587 AverListInner::Concat { left, right, .. } => {
588 if left.is_empty() {
589 current = right;
590 continue;
591 }
592 rights.push(right.clone());
593 current = left;
594 }
595 AverListInner::Segments {
596 current: head_segment,
597 rest,
598 start,
599 ..
600 } => {
601 let (head, tail) = head_segment.uncons()?;
602 return Some((head, Self::segments_rc(tail, Rc::clone(rest), *start)));
603 }
604 }
605 }
606 }
607
608 pub fn uncons_cloned(&self) -> Option<(T, Self)>
609 where
610 T: Clone,
611 {
612 self.uncons().map(|(head, tail)| (head.clone(), tail))
613 }
614
615 pub fn empty() -> Self {
616 Self::from_vec(vec![])
617 }
618
619 pub fn from_vec(items: Vec<T>) -> Self {
620 Self {
621 inner: Rc::new(AverListInner::Flat {
622 items: Rc::new(items),
623 start: 0,
624 }),
625 }
626 }
627
628 pub fn from_rc_vec(items: Rc<Vec<T>>) -> Self {
630 Self {
631 inner: Rc::new(AverListInner::Flat { items, start: 0 }),
632 }
633 }
634
635 pub fn into_rc_vec(&self) -> Rc<Vec<T>>
637 where
638 T: Clone,
639 {
640 match self.inner.as_ref() {
641 AverListInner::Flat { items, start } if *start == 0 => Rc::clone(items),
642 _ => Rc::new(self.to_vec()),
643 }
644 }
645
646 pub fn len(&self) -> usize {
647 match self.inner.as_ref() {
648 AverListInner::Flat { items, start } => items.len().saturating_sub(*start),
649 AverListInner::Prepend { len, .. }
650 | AverListInner::Concat { len, .. }
651 | AverListInner::Segments { len, .. } => *len,
652 }
653 }
654
655 pub fn is_empty(&self) -> bool {
656 self.len() == 0
657 }
658
659 pub fn get(&self, index: usize) -> Option<&T> {
660 let mut current = self;
661 let mut remaining = index;
662
663 loop {
664 match current.inner.as_ref() {
665 AverListInner::Flat { items, start } => {
666 return items.get(start.saturating_add(remaining));
667 }
668 AverListInner::Prepend { head, tail, .. } => {
669 if remaining == 0 {
670 return Some(head);
671 }
672 remaining -= 1;
673 current = tail;
674 }
675 AverListInner::Concat { left, right, .. } => {
676 let left_len = left.len();
677 if remaining < left_len {
678 current = left;
679 } else {
680 remaining -= left_len;
681 current = right;
682 }
683 }
684 AverListInner::Segments {
685 current: head_segment,
686 rest,
687 start,
688 ..
689 } => {
690 let head_len = head_segment.len();
691 if remaining < head_len {
692 current = head_segment;
693 } else {
694 remaining -= head_len;
695 let mut found = None;
696 for part in &rest[*start..] {
697 let part_len = part.len();
698 if remaining < part_len {
699 found = Some(part);
700 break;
701 }
702 remaining -= part_len;
703 }
704 current = found?;
705 }
706 }
707 }
708 }
709 }
710
711 pub fn first(&self) -> Option<&T> {
712 self.get(0)
713 }
714
715 pub fn as_slice(&self) -> Option<&[T]> {
716 match self.inner.as_ref() {
717 AverListInner::Flat { items, start } => Some(items.get(*start..).unwrap_or(&[])),
718 AverListInner::Prepend { .. }
719 | AverListInner::Concat { .. }
720 | AverListInner::Segments { .. } => None,
721 }
722 }
723
724 pub fn iter(&self) -> AverListIter<'_, T> {
725 AverListIter {
726 stack: vec![ListCursor::Node(self)],
727 remaining: self.len(),
728 }
729 }
730
731 pub fn tail(&self) -> Option<Self> {
732 match self.inner.as_ref() {
733 AverListInner::Flat { items, start } => Self::flat_tail(items, *start),
734 AverListInner::Prepend { tail, .. } => Some(tail.clone()),
735 AverListInner::Concat { .. } | AverListInner::Segments { .. } => {
736 self.uncons().map(|(_, tail)| tail)
737 }
738 }
739 }
740
741 pub fn prepend(item: T, list: &Self) -> Self {
742 if list.is_empty() {
743 return Self::from_vec(vec![item]);
744 }
745 Self {
746 inner: Rc::new(AverListInner::Prepend {
747 head: item,
748 tail: list.clone(),
749 len: list.len() + 1,
750 }),
751 }
752 }
753
754 pub fn concat(left: &Self, right: &Self) -> Self {
755 if left.is_empty() {
756 return right.clone();
757 }
758 if right.is_empty() {
759 return left.clone();
760 }
761 Self::concat_node(left, right)
762 }
763
764 pub fn append(list: &Self, item: T) -> Self {
765 let singleton = Self::from_vec(vec![item]);
766 if list.is_empty() {
767 return singleton;
768 }
769
770 match list.inner.as_ref() {
771 AverListInner::Segments {
772 current,
773 rest,
774 start,
775 ..
776 } => {
777 let mut parts = rest[*start..].to_vec();
778 if let Some(last) = parts.last_mut() {
779 if last.len() < LIST_APPEND_CHUNK_LIMIT {
780 *last = Self::concat(last, &singleton);
781 } else {
782 parts.push(singleton);
783 }
784 } else {
785 parts.push(singleton);
786 }
787 Self::segments_rc(current.clone(), Rc::new(parts), 0)
788 }
789 _ if list.len() < LIST_APPEND_CHUNK_LIMIT => Self::concat(list, &singleton),
790 _ => Self::segments_rc(list.clone(), Rc::new(vec![singleton]), 0),
791 }
792 }
793
794 pub fn to_vec(&self) -> Vec<T>
795 where
796 T: Clone,
797 {
798 let mut out = Vec::with_capacity(self.len());
799 out.extend(self.iter().cloned());
800 out
801 }
802
803 pub fn reverse(&self) -> Self
804 where
805 T: Clone,
806 {
807 let mut out = self.to_vec();
808 out.reverse();
809 Self::from_vec(out)
810 }
811
812 pub fn contains(&self, item: &T) -> bool
813 where
814 T: PartialEq,
815 {
816 self.iter().any(|x| x == item)
817 }
818}
819
820impl<'a, T> Iterator for AverListIter<'a, T> {
821 type Item = &'a T;
822
823 fn next(&mut self) -> Option<Self::Item> {
824 while let Some(cursor) = self.stack.pop() {
825 match cursor {
826 ListCursor::Slice(items, index) => {
827 if let Some(item) = items.get(index) {
828 self.stack.push(ListCursor::Slice(items, index + 1));
829 self.remaining = self.remaining.saturating_sub(1);
830 return Some(item);
831 }
832 }
833 ListCursor::Node(list) => match list.inner.as_ref() {
834 AverListInner::Flat { items, start } => {
835 let slice = items.get(*start..).unwrap_or(&[]);
836 if !slice.is_empty() {
837 self.stack.push(ListCursor::Slice(slice, 0));
838 }
839 }
840 AverListInner::Prepend { head, tail, .. } => {
841 self.stack.push(ListCursor::Node(tail));
842 self.remaining = self.remaining.saturating_sub(1);
843 return Some(head);
844 }
845 AverListInner::Concat { left, right, .. } => {
846 self.stack.push(ListCursor::Node(right));
847 self.stack.push(ListCursor::Node(left));
848 }
849 AverListInner::Segments {
850 current,
851 rest,
852 start,
853 ..
854 } => {
855 let slice = rest.get(*start..).unwrap_or(&[]);
856 if !slice.is_empty() {
857 self.stack.push(ListCursor::SegmentSlice(slice, 0));
858 }
859 self.stack.push(ListCursor::Node(current));
860 }
861 },
862 ListCursor::SegmentSlice(items, index) => {
863 if let Some(item) = items.get(index) {
864 self.stack.push(ListCursor::SegmentSlice(items, index + 1));
865 self.stack.push(ListCursor::Node(item));
866 }
867 }
868 }
869 }
870 None
871 }
872
873 fn size_hint(&self) -> (usize, Option<usize>) {
874 (self.remaining, Some(self.remaining))
875 }
876}
877
878impl<T> ExactSizeIterator for AverListIter<'_, T> {
879 fn len(&self) -> usize {
880 self.remaining
881 }
882}
883
884impl<T> FusedIterator for AverListIter<'_, T> {}
885
886impl<'a, T> IntoIterator for &'a AverList<T> {
887 type Item = &'a T;
888 type IntoIter = AverListIter<'a, T>;
889
890 fn into_iter(self) -> Self::IntoIter {
891 self.iter()
892 }
893}
894
895impl<T: Clone> IntoIterator for AverList<T> {
896 type Item = T;
897 type IntoIter = std::vec::IntoIter<T>;
898
899 fn into_iter(self) -> Self::IntoIter {
900 self.to_vec().into_iter()
901 }
902}
903
904impl<T: fmt::Debug> fmt::Debug for AverList<T> {
905 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
906 f.debug_list().entries(self.iter()).finish()
907 }
908}
909
910impl<T: PartialEq> PartialEq for AverList<T> {
911 fn eq(&self, other: &Self) -> bool {
912 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a == b)
913 }
914}
915
916impl<T: Eq> Eq for AverList<T> {}
917
918impl<T: Hash> Hash for AverList<T> {
919 fn hash<H: Hasher>(&self, state: &mut H) {
920 8u8.hash(state);
921 self.len().hash(state);
922 for item in self.iter() {
923 item.hash(state);
924 }
925 }
926}
927
928pub fn list_uncons<T>(list: &AverList<T>) -> Option<(&T, AverList<T>)> {
929 list.uncons()
930}
931
932pub fn list_uncons_cloned<T: Clone>(list: &AverList<T>) -> Option<(T, AverList<T>)> {
933 list.uncons_cloned()
934}
935
936#[macro_export]
938macro_rules! aver_list_match {
939 ($list:expr, [] => $empty:expr, [$head:ident, $tail:ident] => $cons:expr) => {{
940 let __aver_list = $list;
941 if __aver_list.is_empty() {
942 $empty
943 } else if let ::core::option::Option::Some(($head, $tail)) =
944 $crate::list_uncons_cloned(&__aver_list)
945 {
946 $cons
947 } else {
948 panic!("Aver: non-exhaustive list match")
949 }
950 }};
951}
952
953pub fn string_join<S: AsRef<str>>(parts: &AverList<S>, sep: &str) -> String {
954 let mut iter = parts.iter();
955 let Some(first) = iter.next() else {
956 return String::new();
957 };
958 let mut out = first.as_ref().to_string();
959 for part in iter {
960 out.push_str(sep);
961 out.push_str(part.as_ref());
962 }
963 out
964}
965
966#[cfg(test)]
967mod tests {
968 use super::{
969 AverList, AverListInner, LIST_APPEND_CHUNK_LIMIT, aver_display, env_set, string_slice,
970 };
971
972 #[test]
973 fn prepend_and_tail_share_structure() {
974 let base = AverList::from_vec(vec![2, 3]);
975 let full = AverList::prepend(1, &base);
976 assert_eq!(full.first(), Some(&1));
977 assert_eq!(full.tail().unwrap(), base);
978 }
979
980 #[test]
981 fn concat_and_iter_preserve_order() {
982 let left = AverList::from_vec(vec![1, 2]);
983 let right = AverList::from_vec(vec![3, 4]);
984 let joined = AverList::concat(&left, &right);
985 assert_eq!(joined.to_vec(), vec![1, 2, 3, 4]);
986 }
987
988 #[test]
989 fn dropping_deep_prepend_chain_does_not_overflow() {
990 let mut list = AverList::empty();
991 for value in 0..200_000 {
992 list = AverList::prepend(value, &list);
993 }
994
995 assert_eq!(list.len(), 200_000);
996 drop(list);
997 }
998
999 #[test]
1000 fn tail_of_deep_append_chain_does_not_overflow() {
1001 let mut list = AverList::empty();
1002 for value in 0..200_000 {
1003 list = AverList::append(&list, value);
1004 }
1005
1006 let tail = list.tail().expect("non-empty list must have a tail");
1007 assert_eq!(tail.len(), 199_999);
1008 assert_eq!(tail.first(), Some(&1));
1009 }
1010
1011 #[test]
1012 fn list_uncons_of_deep_append_chain_does_not_overflow() {
1013 let mut list = AverList::empty();
1014 for value in 0..200_000 {
1015 list = AverList::append(&list, value);
1016 }
1017
1018 let (head, tail) = super::list_uncons(&list).expect("non-empty list must uncons");
1019 assert_eq!(*head, 0);
1020 assert_eq!(tail.len(), 199_999);
1021 assert_eq!(tail.first(), Some(&1));
1022 }
1023
1024 #[test]
1025 fn cloned_uncons_preserves_append_chain_tail_contents() {
1026 let mut list = AverList::empty();
1027 for value in 0..5 {
1028 list = AverList::append(&list, value);
1029 }
1030
1031 let (head, tail) = super::list_uncons_cloned(&list).expect("non-empty list must uncons");
1032 assert_eq!(head, 0);
1033 assert_eq!(tail.to_vec(), vec![1, 2, 3, 4]);
1034 }
1035
1036 #[test]
1037 fn get_reads_flat_list_in_place() {
1038 let list = AverList::from_vec(vec![10, 20, 30]);
1039
1040 assert_eq!(list.get(0), Some(&10));
1041 assert_eq!(list.get(2), Some(&30));
1042 assert_eq!(list.get(3), None);
1043 }
1044
1045 #[test]
1046 fn get_walks_concat_and_prepend_without_flattening() {
1047 let base = AverList::from_vec(vec![2, 3]);
1048 let prepended = AverList::prepend(1, &base);
1049 let joined = AverList::concat(&prepended, &AverList::from_vec(vec![4, 5]));
1050
1051 assert_eq!(joined.get(0), Some(&1));
1052 assert_eq!(joined.get(2), Some(&3));
1053 assert_eq!(joined.get(4), Some(&5));
1054 assert_eq!(joined.get(5), None);
1055 }
1056
1057 #[test]
1058 fn repeated_tail_over_append_chain_preserves_all_items() {
1059 let mut list = AverList::empty();
1060 for value in 0..6 {
1061 list = AverList::append(&list, value);
1062 }
1063
1064 let mut rest = list;
1065 let mut seen = Vec::new();
1066 while let Some((head, tail)) = super::list_uncons(&rest) {
1067 seen.push(*head);
1068 rest = tail;
1069 }
1070
1071 assert_eq!(seen, vec![0, 1, 2, 3, 4, 5]);
1072 }
1073
1074 #[test]
1075 fn append_promotes_long_right_spines_into_segments() {
1076 let mut list = AverList::empty();
1077 for value in 0..200 {
1078 list = AverList::append(&list, value);
1079 }
1080
1081 match list.inner.as_ref() {
1082 AverListInner::Segments {
1083 current,
1084 rest,
1085 start,
1086 ..
1087 } => {
1088 assert_eq!(current.len(), LIST_APPEND_CHUNK_LIMIT);
1089 assert_eq!(rest[*start].len(), 72);
1090 }
1091 other => panic!(
1092 "expected segmented append shape, got {}",
1093 aver_display_shape(other)
1094 ),
1095 }
1096 }
1097
1098 #[test]
1099 fn get_walks_segmented_append_chain_without_losing_order() {
1100 let mut list = AverList::empty();
1101 for value in 0..300 {
1102 list = AverList::append(&list, value);
1103 }
1104
1105 assert_eq!(list.get(0), Some(&0));
1106 assert_eq!(list.get(127), Some(&127));
1107 assert_eq!(list.get(128), Some(&128));
1108 assert_eq!(list.get(255), Some(&255));
1109 assert_eq!(list.get(299), Some(&299));
1110 assert_eq!(list.get(300), None);
1111 }
1112
1113 #[test]
1114 fn aver_display_quotes_strings_inside_lists() {
1115 let parts = AverList::from_vec(vec!["a".to_string(), "b".to_string()]);
1116 assert_eq!(aver_display(&parts), "[\"a\", \"b\"]");
1117 }
1118
1119 #[test]
1120 fn string_slice_uses_code_point_indices() {
1121 assert_eq!(string_slice("zażółć", 1, 4), "ażó");
1122 }
1123
1124 #[test]
1125 fn string_slice_clamps_negative_indices() {
1126 assert_eq!(string_slice("hello", -2, 2), "he");
1127 assert_eq!(string_slice("hello", 1, -1), "");
1128 }
1129
1130 #[test]
1131 fn env_set_rejects_invalid_keys() {
1132 assert_eq!(
1133 env_set("", "x"),
1134 Err("Env.set: key must not be empty".to_string())
1135 );
1136 assert_eq!(
1137 env_set("A=B", "x"),
1138 Err("Env.set: key must not contain '='".to_string())
1139 );
1140 }
1141
1142 fn aver_display_shape<T>(inner: &AverListInner<T>) -> &'static str {
1143 match inner {
1144 AverListInner::Flat { .. } => "Flat",
1145 AverListInner::Prepend { .. } => "Prepend",
1146 AverListInner::Concat { .. } => "Concat",
1147 AverListInner::Segments { .. } => "Segments",
1148 }
1149 }
1150}