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