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