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