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