recoco_utils/
immutable.rs

1// ReCoco is a Rust-only fork of CocoIndex, by [CocoIndex](https://CocoIndex)
2// Original code from CocoIndex is copyrighted by CocoIndex
3// SPDX-FileCopyrightText: 2025-2026 CocoIndex (upstream)
4// SPDX-FileContributor: CocoIndex Contributors
5//
6// All modifications from the upstream for ReCoco are copyrighted by Knitli Inc.
7// SPDX-FileCopyrightText: 2026 Knitli Inc. (ReCoco)
8// SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
9//
10// Both the upstream CocoIndex code and the ReCoco modifications are licensed under the Apache-2.0 License.
11// SPDX-License-Identifier: Apache-2.0
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
14pub enum RefList<'a, T> {
15    #[default]
16    Nil,
17
18    Cons(T, &'a RefList<'a, T>),
19}
20
21impl<'a, T> RefList<'a, T> {
22    pub fn prepend(&'a self, head: T) -> Self {
23        Self::Cons(head, self)
24    }
25
26    pub fn iter(&'a self) -> impl Iterator<Item = &'a T> {
27        self
28    }
29
30    pub fn head(&'a self) -> Option<&'a T> {
31        match self {
32            RefList::Nil => None,
33            RefList::Cons(head, _) => Some(head),
34        }
35    }
36
37    pub fn headn(&'a self, n: usize) -> Option<&'a T> {
38        match self {
39            RefList::Nil => None,
40            RefList::Cons(head, tail) => {
41                if n == 0 {
42                    Some(head)
43                } else {
44                    tail.headn(n - 1)
45                }
46            }
47        }
48    }
49
50    pub fn tail(&'a self) -> Option<&'a RefList<'a, T>> {
51        match self {
52            RefList::Nil => None,
53            RefList::Cons(_, tail) => Some(tail),
54        }
55    }
56
57    pub fn tailn(&'a self, n: usize) -> Option<&'a RefList<'a, T>> {
58        if n == 0 {
59            Some(self)
60        } else {
61            match self {
62                RefList::Nil => None,
63                RefList::Cons(_, tail) => tail.tailn(n - 1),
64            }
65        }
66    }
67}
68
69impl<'a, T> Iterator for &'a RefList<'a, T> {
70    type Item = &'a T;
71
72    fn next(&mut self) -> Option<Self::Item> {
73        let current = *self;
74        match current {
75            RefList::Nil => None,
76            RefList::Cons(head, tail) => {
77                *self = *tail;
78                Some(head)
79            }
80        }
81    }
82}