Skip to main content

oxihuman_core/
sequence_map.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5//! An ordered map that preserves insertion order and supports sequence access.
6
7/// Entry in the sequence map.
8#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct SeqEntry<V> {
11    pub key: String,
12    pub value: V,
13    pub seq: u64,
14}
15
16/// Map that preserves insertion order and provides sequence-numbered access.
17#[allow(dead_code)]
18pub struct SequenceMap<V> {
19    entries: Vec<SeqEntry<V>>,
20    next_seq: u64,
21}
22
23#[allow(dead_code)]
24impl<V: Clone> SequenceMap<V> {
25    pub fn new() -> Self {
26        Self {
27            entries: Vec::new(),
28            next_seq: 0,
29        }
30    }
31
32    pub fn insert(&mut self, key: &str, value: V) -> u64 {
33        let seq = self.next_seq;
34        self.next_seq += 1;
35        if let Some(e) = self.entries.iter_mut().find(|e| e.key == key) {
36            e.value = value;
37            e.seq = seq;
38        } else {
39            self.entries.push(SeqEntry {
40                key: key.to_string(),
41                value,
42                seq,
43            });
44        }
45        seq
46    }
47
48    pub fn remove(&mut self, key: &str) -> bool {
49        let before = self.entries.len();
50        self.entries.retain(|e| e.key != key);
51        self.entries.len() < before
52    }
53
54    pub fn get(&self, key: &str) -> Option<&V> {
55        self.entries.iter().find(|e| e.key == key).map(|e| &e.value)
56    }
57
58    pub fn get_by_index(&self, index: usize) -> Option<&SeqEntry<V>> {
59        self.entries.get(index)
60    }
61
62    pub fn index_of(&self, key: &str) -> Option<usize> {
63        self.entries.iter().position(|e| e.key == key)
64    }
65
66    pub fn contains(&self, key: &str) -> bool {
67        self.entries.iter().any(|e| e.key == key)
68    }
69
70    pub fn len(&self) -> usize {
71        self.entries.len()
72    }
73
74    pub fn is_empty(&self) -> bool {
75        self.entries.is_empty()
76    }
77
78    pub fn keys(&self) -> Vec<&str> {
79        self.entries.iter().map(|e| e.key.as_str()).collect()
80    }
81
82    pub fn values(&self) -> Vec<&V> {
83        self.entries.iter().map(|e| &e.value).collect()
84    }
85
86    pub fn clear(&mut self) {
87        self.entries.clear();
88    }
89
90    pub fn next_seq(&self) -> u64 {
91        self.next_seq
92    }
93
94    pub fn seq_of(&self, key: &str) -> Option<u64> {
95        self.entries.iter().find(|e| e.key == key).map(|e| e.seq)
96    }
97}
98
99impl<V: Clone> Default for SequenceMap<V> {
100    fn default() -> Self {
101        Self::new()
102    }
103}
104
105pub fn new_sequence_map<V: Clone>() -> SequenceMap<V> {
106    SequenceMap::new()
107}
108
109#[cfg(test)]
110mod tests {
111    use super::*;
112
113    #[test]
114    fn insert_and_get() {
115        let mut m: SequenceMap<i32> = new_sequence_map();
116        m.insert("a", 1);
117        assert_eq!(m.get("a"), Some(&1));
118    }
119
120    #[test]
121    fn preserves_order() {
122        let mut m: SequenceMap<i32> = new_sequence_map();
123        m.insert("first", 1);
124        m.insert("second", 2);
125        assert_eq!(m.keys(), vec!["first", "second"]);
126    }
127
128    #[test]
129    fn update_in_place() {
130        let mut m: SequenceMap<i32> = new_sequence_map();
131        m.insert("k", 1);
132        m.insert("k", 99);
133        assert_eq!(m.get("k"), Some(&99));
134        assert_eq!(m.len(), 1);
135    }
136
137    #[test]
138    fn remove_entry() {
139        let mut m: SequenceMap<i32> = new_sequence_map();
140        m.insert("x", 5);
141        assert!(m.remove("x"));
142        assert!(!m.contains("x"));
143    }
144
145    #[test]
146    fn index_of() {
147        let mut m: SequenceMap<i32> = new_sequence_map();
148        m.insert("a", 1);
149        m.insert("b", 2);
150        assert_eq!(m.index_of("b"), Some(1));
151    }
152
153    #[test]
154    fn get_by_index() {
155        let mut m: SequenceMap<i32> = new_sequence_map();
156        m.insert("z", 7);
157        let e = m.get_by_index(0).expect("should succeed");
158        assert_eq!(e.key, "z");
159    }
160
161    #[test]
162    fn seq_increments() {
163        let mut m: SequenceMap<i32> = new_sequence_map();
164        let s1 = m.insert("a", 1);
165        let s2 = m.insert("b", 2);
166        assert!(s2 > s1);
167    }
168
169    #[test]
170    fn is_empty() {
171        let m: SequenceMap<i32> = new_sequence_map();
172        assert!(m.is_empty());
173    }
174
175    #[test]
176    fn clear() {
177        let mut m: SequenceMap<i32> = new_sequence_map();
178        m.insert("a", 1);
179        m.clear();
180        assert!(m.is_empty());
181    }
182
183    #[test]
184    fn seq_of_known_key() {
185        let mut m: SequenceMap<i32> = new_sequence_map();
186        let seq = m.insert("key", 1);
187        assert_eq!(m.seq_of("key"), Some(seq));
188    }
189}