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};
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::fmt;
34use std::hash::{Hash, Hasher};
35use std::iter::FusedIterator;
36use std::rc::Rc;
37
38const LIST_APPEND_CHUNK_LIMIT: usize = 128;
39
40pub struct AverList<T> {
41 inner: Rc<AverListInner<T>>,
42}
43
44enum AverListInner<T> {
45 Flat {
46 items: Rc<Vec<T>>,
47 start: usize,
48 },
49 Prepend {
50 head: T,
51 tail: AverList<T>,
52 len: usize,
53 },
54 Concat {
55 left: AverList<T>,
56 right: AverList<T>,
57 len: usize,
58 },
59 Segments {
60 current: AverList<T>,
61 rest: Rc<Vec<AverList<T>>>,
62 start: usize,
63 len: usize,
64 },
65}
66
67fn empty_list_inner<T>() -> Rc<AverListInner<T>> {
68 Rc::new(AverListInner::Flat {
69 items: Rc::new(Vec::new()),
70 start: 0,
71 })
72}
73
74fn empty_list<T>(inner: &Rc<AverListInner<T>>) -> AverList<T> {
75 AverList {
76 inner: Rc::clone(inner),
77 }
78}
79
80fn take_list_inner<T>(
81 list: &mut AverList<T>,
82 empty_inner: &Rc<AverListInner<T>>,
83) -> Rc<AverListInner<T>> {
84 let original = std::mem::replace(list, empty_list(empty_inner));
85 original.inner
86}
87
88fn detach_unique_children<T>(
89 inner: &mut AverListInner<T>,
90 empty_inner: &Rc<AverListInner<T>>,
91 pending: &mut Vec<Rc<AverListInner<T>>>,
92) {
93 match inner {
94 AverListInner::Flat { .. } => {}
95 AverListInner::Prepend { tail, .. } => {
96 pending.push(take_list_inner(tail, empty_inner));
97 }
98 AverListInner::Concat { left, right, .. } => {
99 pending.push(take_list_inner(left, empty_inner));
100 pending.push(take_list_inner(right, empty_inner));
101 }
102 AverListInner::Segments { current, rest, .. } => {
103 pending.push(take_list_inner(current, empty_inner));
104 let rest_rc = std::mem::replace(rest, Rc::new(Vec::new()));
105 if let Ok(mut rest_vec) = Rc::try_unwrap(rest_rc) {
106 for part in &mut rest_vec {
107 pending.push(take_list_inner(part, empty_inner));
108 }
109 }
110 }
111 }
112}
113
114impl<T> Drop for AverListInner<T> {
115 fn drop(&mut self) {
116 if matches!(self, AverListInner::Flat { .. }) {
117 return;
118 }
119
120 let empty_inner = empty_list_inner();
121 let mut pending = Vec::new();
122
123 detach_unique_children(self, &empty_inner, &mut pending);
126
127 while let Some(child) = pending.pop() {
128 if let Ok(mut child_inner) = Rc::try_unwrap(child) {
129 detach_unique_children(&mut child_inner, &empty_inner, &mut pending);
130 }
131 }
132 }
133}
134
135#[derive(Clone)]
136enum ListCursor<'a, T> {
137 Node(&'a AverList<T>),
138 Slice(&'a [T], usize),
139 SegmentSlice(&'a [AverList<T>], usize),
140}
141
142pub struct AverListIter<'a, T> {
143 stack: Vec<ListCursor<'a, T>>,
144 remaining: usize,
145}
146
147impl<T> Clone for AverList<T> {
148 fn clone(&self) -> Self {
149 Self {
150 inner: Rc::clone(&self.inner),
151 }
152 }
153}
154
155impl<T> AverList<T> {
156 fn concat_node(left: &Self, right: &Self) -> Self {
157 Self {
158 inner: Rc::new(AverListInner::Concat {
159 left: left.clone(),
160 right: right.clone(),
161 len: left.len() + right.len(),
162 }),
163 }
164 }
165
166 fn segments_rc(mut current: Self, rest: Rc<Vec<Self>>, mut start: usize) -> Self {
167 while current.is_empty() {
168 if let Some(next) = rest.get(start).cloned() {
169 current = next;
170 start += 1;
171 } else {
172 return Self::empty();
173 }
174 }
175
176 if start >= rest.len() {
177 return current;
178 }
179
180 let len = current.len() + rest[start..].iter().map(AverList::len).sum::<usize>();
181 Self {
182 inner: Rc::new(AverListInner::Segments {
183 current,
184 rest,
185 start,
186 len,
187 }),
188 }
189 }
190
191 fn rebuild_from_rights(mut base: Self, mut rights: Vec<Self>) -> Self {
192 while let Some(right) = rights.pop() {
193 base = Self::concat(&base, &right);
194 }
195 base
196 }
197
198 fn flat_tail(items: &Rc<Vec<T>>, start: usize) -> Option<Self> {
199 if start >= items.len() {
200 return None;
201 }
202 if start + 1 >= items.len() {
203 return Some(Self::empty());
204 }
205 Some(Self {
206 inner: Rc::new(AverListInner::Flat {
207 items: Rc::clone(items),
208 start: start + 1,
209 }),
210 })
211 }
212
213 fn uncons(&self) -> Option<(&T, Self)> {
214 let mut rights = Vec::new();
215 let mut current = self;
216
217 loop {
218 match current.inner.as_ref() {
219 AverListInner::Flat { items, start } => {
220 let head = items.get(*start)?;
221 let tail = Self::flat_tail(items, *start)?;
222 return Some((head, Self::rebuild_from_rights(tail, rights)));
223 }
224 AverListInner::Prepend { head, tail, .. } => {
225 return Some((head, Self::rebuild_from_rights(tail.clone(), rights)));
226 }
227 AverListInner::Concat { left, right, .. } => {
228 if left.is_empty() {
229 current = right;
230 continue;
231 }
232 rights.push(right.clone());
233 current = left;
234 }
235 AverListInner::Segments {
236 current: head_segment,
237 rest,
238 start,
239 ..
240 } => {
241 let (head, tail) = head_segment.uncons()?;
242 return Some((head, Self::segments_rc(tail, Rc::clone(rest), *start)));
243 }
244 }
245 }
246 }
247
248 pub fn uncons_cloned(&self) -> Option<(T, Self)>
249 where
250 T: Clone,
251 {
252 self.uncons().map(|(head, tail)| (head.clone(), tail))
253 }
254
255 pub fn empty() -> Self {
256 Self::from_vec(vec![])
257 }
258
259 pub fn from_vec(items: Vec<T>) -> Self {
260 Self {
261 inner: Rc::new(AverListInner::Flat {
262 items: Rc::new(items),
263 start: 0,
264 }),
265 }
266 }
267
268 pub fn len(&self) -> usize {
269 match self.inner.as_ref() {
270 AverListInner::Flat { items, start } => items.len().saturating_sub(*start),
271 AverListInner::Prepend { len, .. }
272 | AverListInner::Concat { len, .. }
273 | AverListInner::Segments { len, .. } => *len,
274 }
275 }
276
277 pub fn is_empty(&self) -> bool {
278 self.len() == 0
279 }
280
281 pub fn get(&self, index: usize) -> Option<&T> {
282 let mut current = self;
283 let mut remaining = index;
284
285 loop {
286 match current.inner.as_ref() {
287 AverListInner::Flat { items, start } => {
288 return items.get(start.saturating_add(remaining));
289 }
290 AverListInner::Prepend { head, tail, .. } => {
291 if remaining == 0 {
292 return Some(head);
293 }
294 remaining -= 1;
295 current = tail;
296 }
297 AverListInner::Concat { left, right, .. } => {
298 let left_len = left.len();
299 if remaining < left_len {
300 current = left;
301 } else {
302 remaining -= left_len;
303 current = right;
304 }
305 }
306 AverListInner::Segments {
307 current: head_segment,
308 rest,
309 start,
310 ..
311 } => {
312 let head_len = head_segment.len();
313 if remaining < head_len {
314 current = head_segment;
315 } else {
316 remaining -= head_len;
317 let mut found = None;
318 for part in &rest[*start..] {
319 let part_len = part.len();
320 if remaining < part_len {
321 found = Some(part);
322 break;
323 }
324 remaining -= part_len;
325 }
326 current = found?;
327 }
328 }
329 }
330 }
331 }
332
333 pub fn first(&self) -> Option<&T> {
334 self.get(0)
335 }
336
337 pub fn as_slice(&self) -> Option<&[T]> {
338 match self.inner.as_ref() {
339 AverListInner::Flat { items, start } => Some(items.get(*start..).unwrap_or(&[])),
340 AverListInner::Prepend { .. }
341 | AverListInner::Concat { .. }
342 | AverListInner::Segments { .. } => None,
343 }
344 }
345
346 pub fn iter(&self) -> AverListIter<'_, T> {
347 AverListIter {
348 stack: vec![ListCursor::Node(self)],
349 remaining: self.len(),
350 }
351 }
352
353 pub fn tail(&self) -> Option<Self> {
354 match self.inner.as_ref() {
355 AverListInner::Flat { items, start } => Self::flat_tail(items, *start),
356 AverListInner::Prepend { tail, .. } => Some(tail.clone()),
357 AverListInner::Concat { .. } | AverListInner::Segments { .. } => {
358 self.uncons().map(|(_, tail)| tail)
359 }
360 }
361 }
362
363 pub fn prepend(item: T, list: &Self) -> Self {
364 if list.is_empty() {
365 return Self::from_vec(vec![item]);
366 }
367 Self {
368 inner: Rc::new(AverListInner::Prepend {
369 head: item,
370 tail: list.clone(),
371 len: list.len() + 1,
372 }),
373 }
374 }
375
376 pub fn concat(left: &Self, right: &Self) -> Self {
377 if left.is_empty() {
378 return right.clone();
379 }
380 if right.is_empty() {
381 return left.clone();
382 }
383 Self::concat_node(left, right)
384 }
385
386 pub fn append(list: &Self, item: T) -> Self {
387 let singleton = Self::from_vec(vec![item]);
388 if list.is_empty() {
389 return singleton;
390 }
391
392 match list.inner.as_ref() {
393 AverListInner::Segments {
394 current,
395 rest,
396 start,
397 ..
398 } => {
399 let mut parts = rest[*start..].to_vec();
400 if let Some(last) = parts.last_mut() {
401 if last.len() < LIST_APPEND_CHUNK_LIMIT {
402 *last = Self::concat(last, &singleton);
403 } else {
404 parts.push(singleton);
405 }
406 } else {
407 parts.push(singleton);
408 }
409 Self::segments_rc(current.clone(), Rc::new(parts), 0)
410 }
411 _ if list.len() < LIST_APPEND_CHUNK_LIMIT => Self::concat(list, &singleton),
412 _ => Self::segments_rc(list.clone(), Rc::new(vec![singleton]), 0),
413 }
414 }
415
416 pub fn to_vec(&self) -> Vec<T>
417 where
418 T: Clone,
419 {
420 let mut out = Vec::with_capacity(self.len());
421 out.extend(self.iter().cloned());
422 out
423 }
424
425 pub fn reverse(&self) -> Self
426 where
427 T: Clone,
428 {
429 let mut out = self.to_vec();
430 out.reverse();
431 Self::from_vec(out)
432 }
433
434 pub fn contains(&self, item: &T) -> bool
435 where
436 T: PartialEq,
437 {
438 self.iter().any(|x| x == item)
439 }
440}
441
442impl<'a, T> Iterator for AverListIter<'a, T> {
443 type Item = &'a T;
444
445 fn next(&mut self) -> Option<Self::Item> {
446 while let Some(cursor) = self.stack.pop() {
447 match cursor {
448 ListCursor::Slice(items, index) => {
449 if let Some(item) = items.get(index) {
450 self.stack.push(ListCursor::Slice(items, index + 1));
451 self.remaining = self.remaining.saturating_sub(1);
452 return Some(item);
453 }
454 }
455 ListCursor::Node(list) => match list.inner.as_ref() {
456 AverListInner::Flat { items, start } => {
457 let slice = items.get(*start..).unwrap_or(&[]);
458 if !slice.is_empty() {
459 self.stack.push(ListCursor::Slice(slice, 0));
460 }
461 }
462 AverListInner::Prepend { head, tail, .. } => {
463 self.stack.push(ListCursor::Node(tail));
464 self.remaining = self.remaining.saturating_sub(1);
465 return Some(head);
466 }
467 AverListInner::Concat { left, right, .. } => {
468 self.stack.push(ListCursor::Node(right));
469 self.stack.push(ListCursor::Node(left));
470 }
471 AverListInner::Segments {
472 current,
473 rest,
474 start,
475 ..
476 } => {
477 let slice = rest.get(*start..).unwrap_or(&[]);
478 if !slice.is_empty() {
479 self.stack.push(ListCursor::SegmentSlice(slice, 0));
480 }
481 self.stack.push(ListCursor::Node(current));
482 }
483 },
484 ListCursor::SegmentSlice(items, index) => {
485 if let Some(item) = items.get(index) {
486 self.stack.push(ListCursor::SegmentSlice(items, index + 1));
487 self.stack.push(ListCursor::Node(item));
488 }
489 }
490 }
491 }
492 None
493 }
494
495 fn size_hint(&self) -> (usize, Option<usize>) {
496 (self.remaining, Some(self.remaining))
497 }
498}
499
500impl<T> ExactSizeIterator for AverListIter<'_, T> {
501 fn len(&self) -> usize {
502 self.remaining
503 }
504}
505
506impl<T> FusedIterator for AverListIter<'_, T> {}
507
508impl<'a, T> IntoIterator for &'a AverList<T> {
509 type Item = &'a T;
510 type IntoIter = AverListIter<'a, T>;
511
512 fn into_iter(self) -> Self::IntoIter {
513 self.iter()
514 }
515}
516
517impl<T: Clone> IntoIterator for AverList<T> {
518 type Item = T;
519 type IntoIter = std::vec::IntoIter<T>;
520
521 fn into_iter(self) -> Self::IntoIter {
522 self.to_vec().into_iter()
523 }
524}
525
526impl<T: fmt::Debug> fmt::Debug for AverList<T> {
527 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
528 f.debug_list().entries(self.iter()).finish()
529 }
530}
531
532impl<T: PartialEq> PartialEq for AverList<T> {
533 fn eq(&self, other: &Self) -> bool {
534 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a == b)
535 }
536}
537
538impl<T: Eq> Eq for AverList<T> {}
539
540impl<T: Hash> Hash for AverList<T> {
541 fn hash<H: Hasher>(&self, state: &mut H) {
542 8u8.hash(state);
543 self.len().hash(state);
544 for item in self.iter() {
545 item.hash(state);
546 }
547 }
548}
549
550pub fn list_uncons<T>(list: &AverList<T>) -> Option<(&T, AverList<T>)> {
551 list.uncons()
552}
553
554pub fn list_uncons_cloned<T: Clone>(list: &AverList<T>) -> Option<(T, AverList<T>)> {
555 list.uncons_cloned()
556}
557
558pub fn string_join<S: AsRef<str>>(parts: &AverList<S>, sep: &str) -> String {
559 let mut iter = parts.iter();
560 let Some(first) = iter.next() else {
561 return String::new();
562 };
563 let mut out = first.as_ref().to_string();
564 for part in iter {
565 out.push_str(sep);
566 out.push_str(part.as_ref());
567 }
568 out
569}
570
571#[cfg(test)]
572mod tests {
573 use super::{
574 AverList, AverListInner, LIST_APPEND_CHUNK_LIMIT, aver_display, env_set, string_slice,
575 };
576
577 #[test]
578 fn prepend_and_tail_share_structure() {
579 let base = AverList::from_vec(vec![2, 3]);
580 let full = AverList::prepend(1, &base);
581 assert_eq!(full.first(), Some(&1));
582 assert_eq!(full.tail().unwrap(), base);
583 }
584
585 #[test]
586 fn concat_and_iter_preserve_order() {
587 let left = AverList::from_vec(vec![1, 2]);
588 let right = AverList::from_vec(vec![3, 4]);
589 let joined = AverList::concat(&left, &right);
590 assert_eq!(joined.to_vec(), vec![1, 2, 3, 4]);
591 }
592
593 #[test]
594 fn dropping_deep_prepend_chain_does_not_overflow() {
595 let mut list = AverList::empty();
596 for value in 0..200_000 {
597 list = AverList::prepend(value, &list);
598 }
599
600 assert_eq!(list.len(), 200_000);
601 drop(list);
602 }
603
604 #[test]
605 fn tail_of_deep_append_chain_does_not_overflow() {
606 let mut list = AverList::empty();
607 for value in 0..200_000 {
608 list = AverList::append(&list, value);
609 }
610
611 let tail = list.tail().expect("non-empty list must have a tail");
612 assert_eq!(tail.len(), 199_999);
613 assert_eq!(tail.first(), Some(&1));
614 }
615
616 #[test]
617 fn list_uncons_of_deep_append_chain_does_not_overflow() {
618 let mut list = AverList::empty();
619 for value in 0..200_000 {
620 list = AverList::append(&list, value);
621 }
622
623 let (head, tail) = super::list_uncons(&list).expect("non-empty list must uncons");
624 assert_eq!(*head, 0);
625 assert_eq!(tail.len(), 199_999);
626 assert_eq!(tail.first(), Some(&1));
627 }
628
629 #[test]
630 fn cloned_uncons_preserves_append_chain_tail_contents() {
631 let mut list = AverList::empty();
632 for value in 0..5 {
633 list = AverList::append(&list, value);
634 }
635
636 let (head, tail) = super::list_uncons_cloned(&list).expect("non-empty list must uncons");
637 assert_eq!(head, 0);
638 assert_eq!(tail.to_vec(), vec![1, 2, 3, 4]);
639 }
640
641 #[test]
642 fn get_reads_flat_list_in_place() {
643 let list = AverList::from_vec(vec![10, 20, 30]);
644
645 assert_eq!(list.get(0), Some(&10));
646 assert_eq!(list.get(2), Some(&30));
647 assert_eq!(list.get(3), None);
648 }
649
650 #[test]
651 fn get_walks_concat_and_prepend_without_flattening() {
652 let base = AverList::from_vec(vec![2, 3]);
653 let prepended = AverList::prepend(1, &base);
654 let joined = AverList::concat(&prepended, &AverList::from_vec(vec![4, 5]));
655
656 assert_eq!(joined.get(0), Some(&1));
657 assert_eq!(joined.get(2), Some(&3));
658 assert_eq!(joined.get(4), Some(&5));
659 assert_eq!(joined.get(5), None);
660 }
661
662 #[test]
663 fn repeated_tail_over_append_chain_preserves_all_items() {
664 let mut list = AverList::empty();
665 for value in 0..6 {
666 list = AverList::append(&list, value);
667 }
668
669 let mut rest = list;
670 let mut seen = Vec::new();
671 while let Some((head, tail)) = super::list_uncons(&rest) {
672 seen.push(*head);
673 rest = tail;
674 }
675
676 assert_eq!(seen, vec![0, 1, 2, 3, 4, 5]);
677 }
678
679 #[test]
680 fn append_promotes_long_right_spines_into_segments() {
681 let mut list = AverList::empty();
682 for value in 0..200 {
683 list = AverList::append(&list, value);
684 }
685
686 match list.inner.as_ref() {
687 AverListInner::Segments {
688 current,
689 rest,
690 start,
691 ..
692 } => {
693 assert_eq!(current.len(), LIST_APPEND_CHUNK_LIMIT);
694 assert_eq!(rest[*start].len(), 72);
695 }
696 other => panic!(
697 "expected segmented append shape, got {}",
698 aver_display_shape(other)
699 ),
700 }
701 }
702
703 #[test]
704 fn get_walks_segmented_append_chain_without_losing_order() {
705 let mut list = AverList::empty();
706 for value in 0..300 {
707 list = AverList::append(&list, value);
708 }
709
710 assert_eq!(list.get(0), Some(&0));
711 assert_eq!(list.get(127), Some(&127));
712 assert_eq!(list.get(128), Some(&128));
713 assert_eq!(list.get(255), Some(&255));
714 assert_eq!(list.get(299), Some(&299));
715 assert_eq!(list.get(300), None);
716 }
717
718 #[test]
719 fn aver_display_quotes_strings_inside_lists() {
720 let parts = AverList::from_vec(vec!["a".to_string(), "b".to_string()]);
721 assert_eq!(aver_display(&parts), "[\"a\", \"b\"]");
722 }
723
724 #[test]
725 fn string_slice_uses_code_point_indices() {
726 assert_eq!(string_slice("zażółć", 1, 4), "ażó");
727 }
728
729 #[test]
730 fn string_slice_clamps_negative_indices() {
731 assert_eq!(string_slice("hello", -2, 2), "he");
732 assert_eq!(string_slice("hello", 1, -1), "");
733 }
734
735 #[test]
736 fn env_set_rejects_invalid_keys() {
737 assert_eq!(
738 env_set("", "x"),
739 Err("Env.set: key must not be empty".to_string())
740 );
741 assert_eq!(
742 env_set("A=B", "x"),
743 Err("Env.set: key must not contain '='".to_string())
744 );
745 }
746
747 fn aver_display_shape<T>(inner: &AverListInner<T>) -> &'static str {
748 match inner {
749 AverListInner::Flat { .. } => "Flat",
750 AverListInner::Prepend { .. } => "Prepend",
751 AverListInner::Concat { .. } => "Concat",
752 AverListInner::Segments { .. } => "Segments",
753 }
754 }
755}