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