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::{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/// Internal builder for the deforestation lowering (0.15 Traversal).
39/// Backs `__buf_*` intrinsics emitted when the compiler fuses
40/// `String.join(<builder>(...), sep)` shapes — `String::with_capacity`
41/// plus `push_str` is exactly the right shape, no GC dance needed.
42/// User code never sees this directly; it lives strictly between
43/// `__buf_new` and `__buf_finalize` inside synthesized helpers.
44pub type Buffer = String;
45
46/// Aver string type: newtype over Rc<str> for O(1) clone and native `+` operator.
47#[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/// Concatenate two AverStr values.
119#[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
128// ── par_execute: parallel execution for independent products (?!) ─────────────────
129
130/// Execute tasks in parallel using scoped threads.
131/// All branches run to completion (`complete` mode).
132pub 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
139/// Execute tasks sequentially, left-to-right. Used by `sequential` mode.
140/// Valid per the language spec (the fully-sequential interleave is always
141/// permitted). Available on every target — no threading required.
142///
143/// Signature matches [`par_execute`] (with `Send` bounds) so call sites
144/// can swap implementations without reshaping task boxes.
145pub 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
149/// Execute tasks in parallel with cooperative cancellation (`cancel` mode).
150///
151/// Each task receives a shared `cancelled` flag. When one branch fails, the
152/// flag is set so siblings can check it and bail early. Tasks must call
153/// `cancelled.load(Ordering::Relaxed)` at effect boundaries to cooperate.
154/// Cancellable task: receives a shared cancellation flag, returns Result.
155pub 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
181// ── AverMap: Copy-on-Write HashMap ──────────────────────────────────────────
182//
183// Semantically immutable (like im::HashMap), but when the Rc has a single
184// owner we mutate in place — turning O(log n) persistent-set into O(1)
185// amortized insert.
186
187pub 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    /// O(n) because `&self` preserves the original map.
219    pub fn insert(&self, key: K, value: V) -> Self {
220        self.clone().insert_owned(key, value)
221    }
222
223    /// O(1) amortized if unique owner, O(n) clone if shared.
224    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    /// Rewrite values in place using `Rc::make_mut` (zero-copy when sole owner).
230    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    /// O(n) because `&self` preserves the original map.
238    pub fn remove(&self, key: &K) -> Self {
239        self.clone().remove_owned(key)
240    }
241
242    /// O(1) amortized if unique owner, O(n) clone if shared.
243    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        // Deterministic: sort keys for stable hash
290        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
317// ── AverVector: COW indexed sequence ─────────────────────────────────────────
318
319pub 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    /// O(1) amortized if unique owner, O(n) clone if shared.
343    ///
344    /// Caller must ensure `index < len()`.
345    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    /// O(1) amortized if unique owner, O(n) clone if shared. None if out of bounds.
352    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    /// O(n) because `&self` preserves the original vector.
360    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    /// O(1) — shares Rc<Vec<T>> with the resulting Flat AverList.
381    pub fn to_list(&self) -> AverList<T> {
382        AverList::from_rc_vec(Rc::clone(&self.inner))
383    }
384
385    /// O(1) if list is Flat with start=0 (e.g. after List.reverse), O(n) otherwise.
386    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
422// ── AverList ─────────────────────────────────────────────────────────────────
423
424const 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 eagerly so deep list teardown does not recurse
510        // through nested `Rc<AverListInner<_>>` chains on the Rust call stack.
511        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    /// O(1) if Flat with start=0, wraps existing Rc<Vec<T>> directly.
655    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    /// Extract the backing Rc<Vec<T>> — O(1) if Flat with start=0, O(n) otherwise.
662    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/// Pattern-match on an AverList: empty and cons (head, tail) arms.
963#[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}