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