Skip to main content

aver_rt/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod display;
4#[cfg(feature = "http")]
5pub mod http;
6pub mod http_server;
7#[cfg(feature = "random")]
8pub mod random;
9mod runtime;
10mod service_types;
11pub mod tcp;
12#[cfg(feature = "terminal")]
13pub mod terminal;
14
15pub use display::{AverDisplay, aver_display};
16pub use runtime::{
17    append_text, cli_args, console_error, console_print, console_warn, delete_dir, delete_file,
18    env_get, env_set, list_dir, make_dir, path_exists, read_line, read_text, string_slice,
19    time_now, time_sleep, time_unix_ms, write_text,
20};
21pub use service_types::{Header, HttpRequest, HttpResponse, TcpConnection, TerminalSize};
22
23#[cfg(feature = "terminal")]
24pub use terminal::{
25    TerminalGuard, clear as terminal_clear, disable_raw_mode as terminal_disable_raw_mode,
26    enable_raw_mode as terminal_enable_raw_mode, flush as terminal_flush,
27    hide_cursor as terminal_hide_cursor, move_to as terminal_move_to,
28    print_at_cursor as terminal_print, read_key as terminal_read_key,
29    reset_color as terminal_reset_color, restore_terminal, set_color as terminal_set_color,
30    show_cursor as terminal_show_cursor, size as terminal_size,
31};
32
33use std::collections::HashMap as StdHashMap;
34use std::fmt;
35use std::hash::{Hash, Hasher};
36use std::iter::FusedIterator;
37
38/// Aver string type: newtype over Rc<str> for O(1) clone and native `+` operator.
39#[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/// Concatenate two AverStr values.
111#[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
120// ── par_execute: parallel execution for independent products (?!) ─────────────────
121
122/// Execute tasks in parallel using scoped threads.
123/// All branches run to completion (`complete` mode).
124pub 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
131/// Execute tasks sequentially, left-to-right. Used by `sequential` mode.
132/// Valid per the language spec (the fully-sequential interleave is always
133/// permitted). Available on every target — no threading required.
134///
135/// Signature matches [`par_execute`] (with `Send` bounds) so call sites
136/// can swap implementations without reshaping task boxes.
137pub 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
141/// Execute tasks in parallel with cooperative cancellation (`cancel` mode).
142///
143/// Each task receives a shared `cancelled` flag. When one branch fails, the
144/// flag is set so siblings can check it and bail early. Tasks must call
145/// `cancelled.load(Ordering::Relaxed)` at effect boundaries to cooperate.
146/// Cancellable task: receives a shared cancellation flag, returns Result.
147pub 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
173// ── AverMap: Copy-on-Write HashMap ──────────────────────────────────────────
174//
175// Semantically immutable (like im::HashMap), but when the Rc has a single
176// owner we mutate in place — turning O(log n) persistent-set into O(1)
177// amortized insert.
178
179pub 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    /// O(n) because `&self` preserves the original map.
211    pub fn insert(&self, key: K, value: V) -> Self {
212        self.clone().insert_owned(key, value)
213    }
214
215    /// O(1) amortized if unique owner, O(n) clone if shared.
216    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    /// Rewrite values in place using `Rc::make_mut` (zero-copy when sole owner).
222    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    /// O(n) because `&self` preserves the original map.
230    pub fn remove(&self, key: &K) -> Self {
231        self.clone().remove_owned(key)
232    }
233
234    /// O(1) amortized if unique owner, O(n) clone if shared.
235    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        // Deterministic: sort keys for stable hash
282        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
309// ── AverVector: COW indexed sequence ─────────────────────────────────────────
310
311pub 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    /// O(1) amortized if unique owner, O(n) clone if shared.
335    ///
336    /// Caller must ensure `index < len()`.
337    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    /// O(1) amortized if unique owner, O(n) clone if shared. None if out of bounds.
344    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    /// O(n) because `&self` preserves the original vector.
352    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    /// O(1) — shares Rc<Vec<T>> with the resulting Flat AverList.
373    pub fn to_list(&self) -> AverList<T> {
374        AverList::from_rc_vec(Rc::clone(&self.inner))
375    }
376
377    /// O(1) if list is Flat with start=0 (e.g. after List.reverse), O(n) otherwise.
378    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
414// ── AverList ─────────────────────────────────────────────────────────────────
415
416const 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 eagerly so deep list teardown does not recurse
502        // through nested `Rc<AverListInner<_>>` chains on the Rust call stack.
503        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    /// O(1) if Flat with start=0, wraps existing Rc<Vec<T>> directly.
647    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    /// Extract the backing Rc<Vec<T>> — O(1) if Flat with start=0, O(n) otherwise.
654    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/// Pattern-match on an AverList: empty and cons (head, tail) arms.
955#[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}