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