Skip to main content

obj_alloc/
lib.rs

1#![allow(dead_code)]
2pub mod pair;
3pub mod id_map;
4pub mod deser;
5
6pub use id_map::*;
7pub use pair::*;
8
9use std::ops::{Deref, DerefMut};
10use field_collex::{Collexetable, FieldCollex, FieldValue};
11use field_collex::collex::*;
12use span_core::Span;
13
14pub(crate) fn insert<K,E,V>(id_map: &mut IdMap<K,V>, elem: E) -> Pair<K,E>
15where
16    K: Id,
17    E: Collexetable<V>,
18    V: FieldValue,
19{
20    Pair(
21        id_map.insert(elem.collexate()),
22        elem
23    )
24}
25
26pub(crate) fn extend_from_vec<K,E,V>(id_map: &mut IdMap<K,V>, vec: Vec<E>) -> Vec<Pair<K,E>>
27where
28    K: Id,
29    E: Collexetable<V>,
30    V: FieldValue,
31{
32    let mut other: Vec<Pair<K,E>> = Vec::new();
33    vec.into_iter().for_each(|e|
34        {
35            other.push(insert(id_map, e))
36        }
37    );
38    
39    other
40}
41
42#[derive(Debug, Clone)]
43#[derive(serde::Serialize)]
44#[serde(transparent)]
45pub struct OrdIdMap<K,O,T>
46where
47    K: Id,
48    O: Collexetable<T>,
49    T: FieldValue,
50{
51    #[serde(skip)]
52    pub id_map: IdMap<K,T>,
53    pub collex: FieldCollex<Pair<K,O>,T>
54}
55
56impl<K,E,V> Deref for OrdIdMap<K,E,V>
57where
58    K: Id,
59    E: Collexetable<V>,
60    V: FieldValue,
61{
62    type Target =  FieldCollex<Pair<K,E>,V>;
63    fn deref(&self) -> &Self::Target {
64        &self.collex
65    }
66}
67
68impl<K,E,V> DerefMut for OrdIdMap<K,E,V>
69where
70    K: Id,
71    E: Collexetable<V>,
72    V: FieldValue,
73{
74    fn deref_mut(&mut self) -> &mut Self::Target {
75        &mut self.collex
76    }
77}
78
79
80impl<K, E, V> OrdIdMap<K, E, V>
81where
82    K: Id,
83    E: Collexetable<V>,
84    V: FieldValue,
85{
86    pub fn new(span: Span<V>, unit: V) -> Result<Self, NewFieldCollexError<V>> {
87        Ok(Self{
88            id_map: IdMap::with_id(),
89            collex: FieldCollex::new(span, unit)?,
90        })
91    }
92    
93    pub fn with_capacity(
94        span: Span<V>,
95        unit: V,
96        capacity: usize,
97    ) -> Result<Self, WithCapacityFieldCollexError<V>>
98    {
99        Ok(Self{
100            id_map: IdMap::with_id_capacity(capacity),
101            collex: FieldCollex::with_capacity(span, unit, capacity)?,
102        })
103    }
104    
105    pub fn with_elements(
106        span: Span<V>,
107        unit: V,
108        vec: Vec<E>,
109    ) -> Result<Self, WithElementsFieldCollexError<V>>
110    {
111        let mut id_map = IdMap::with_id();
112        let other = extend_from_vec(&mut id_map, vec);
113        
114        Ok(Self{
115            id_map,
116            collex: FieldCollex::with_elements(span, unit, other)?,
117        })
118    }
119    
120    pub fn extend(&mut self, vec: Vec<E>) {
121        let other = extend_from_vec(&mut self.id_map, vec);
122        self.collex.extend(other)
123    }
124    
125    pub fn try_extend(&mut self, vec: Vec<E>) -> TryExtendResult<Pair<K, E>> {
126        let other = extend_from_vec(&mut self.id_map, vec);
127        self.collex.try_extend(other)
128    }
129    
130    pub fn insert(&mut self, elem: E) -> Result<K, InsertFieldCollexError<E>> {
131        use InsertFieldCollexError::*;
132        let obj = insert(&mut self.id_map, elem);
133        let id = obj.0;
134        self.collex.insert(obj)
135            .map(|_| id)
136            .map_err(|err|
137                {
138                    self.id_map.remove(id);
139                    match err {
140                        OutOfSpan(o) => { OutOfSpan(o.1) }
141                        AlreadyExist(o) => { AlreadyExist(o.1) }
142                    }
143                }
144            )
145    }
146
147    pub fn insert_with_id(&mut self, id: K, elem: E) -> Result<Option<E>, InsertFieldCollexError<E>>  {
148        use InsertFieldCollexError::*;
149        let value = elem.collexate();
150        self.id_map
151            .insert_with_id(id, value)
152            .map(|v|self.collex.remove(v).unwrap());
153
154        self.collex.insert(Pair(id, elem))
155            .map(|_| None)
156            .map_err(|err|
157                {
158                    self.id_map.remove(id);
159                    match err {
160                        OutOfSpan(o) => { OutOfSpan(o.1) }
161                        AlreadyExist(o) => { AlreadyExist(o.1) }
162                    }
163                }
164            )
165    }
166
167    pub fn remove(&mut self, id: K) -> Option<E> {
168        let v = self.id_map.remove(id)?;
169        
170        Some(self.collex
171            .remove(v)
172            .unwrap()
173            .1)
174    }
175    
176    pub fn modify<F,R>(&mut self, id: K, f: F) -> Result<R, ModifyFieldCollexError<(R,E)>>
177    where
178        F: Fn(&mut E) -> R,
179    {
180        use ModifyFieldCollexError::*;
181        let v = self.id_map.get(id).ok_or(CannotFind)?;
182        let (r,new_v) =
183            self.collex
184                .modify(*v,|e| (f(e),e.collexate()) )
185                .map_err(|err|
186                    err.map(|e| (e.0.0, e.1.1))
187                )?;
188        *self.id_map.get_mut(id).unwrap() = new_v;
189        Ok(r)
190    }
191    
192    pub fn try_modify<F,R>(&mut self, id: K, f: F) -> Result<R, ModifyFieldCollexError<R>>
193    where
194        F: Fn(&mut E) -> R,
195    {
196        use ModifyFieldCollexError::*;
197        let v = self.id_map.get(id).ok_or(CannotFind)?;
198        let (r,new_v) =
199            self.collex
200                .try_modify(*v, |e| (f(e),e.collexate()) )
201                .map_err(|err|
202                     err.map(|e| e.0)
203                )?;
204        *self.id_map.get_mut(id).unwrap() = new_v;
205        Ok(r)
206    }
207    
208    pub fn get_with_id(&self, id: K) -> Option<&E> {
209        let v = self.id_map.get(id)?;
210        self.collex.get(*v).map(|v| &v.1)
211    }
212    
213    pub fn into_raw_parts(self) -> (IdMap<K,V>, FieldCollex<Pair<K,E>,V>) {
214        (self.id_map,self.collex)
215    }
216    
217    pub fn from_raw_parts(id_map: IdMap<K,V>, collex: FieldCollex<Pair<K,E>,V>) -> Self {
218        Self {
219            id_map, collex
220        }
221    }
222}
223
224use field_collex::collex::iter::{Iter as CollexIter, IntoIter as CollexIntoIter};
225
226pub struct Iter<'a, K, O, T>
227where
228    K: Id,
229    O: Collexetable<T>,
230    T: FieldValue,
231{
232    inner: CollexIter<'a, Pair<K, O>, T>,
233}
234
235impl<'a, K, O, T> Iterator for Iter<'a, K, O, T>
236where
237    K: Id,
238    O: Collexetable<T>,
239    T: FieldValue,
240{
241    type Item = &'a O;
242    
243    fn next(&mut self) -> Option<Self::Item> {
244        // CollexIter 产出 &Pair<K, O>,我们映射出 &O
245        self.inner.next().map(|pair| &pair.1)
246    }
247    
248    fn size_hint(&self) -> (usize, Option<usize>) {
249        self.inner.size_hint()
250    }
251}
252
253pub struct IntoIter<K, O, T>
254where
255    K: Id,
256    O: Collexetable<T>,
257    T: FieldValue,
258{
259    inner: CollexIntoIter<Pair<K, O>, T>,
260}
261
262impl<K, O, T> Iterator for IntoIter<K, O, T>
263where
264    K: Id,
265    O: Collexetable<T>,
266    T: FieldValue,
267{
268    type Item = O;
269    
270    fn next(&mut self) -> Option<Self::Item> {
271        // CollexIntoIter 产出 Pair<K, O>,我们映射出 O
272        self.inner.next().map(|pair| pair.1)
273    }
274    
275    fn size_hint(&self) -> (usize, Option<usize>) {
276        self.inner.size_hint()
277    }
278}
279
280pub struct Keys<'a, K: id_map::Id, O: field_collex::Collexetable<T>, T: field_collex::FieldValue> {
281    inner: CollexIter<'a, Pair<K, O>, T>,
282}
283
284impl<K, O, T> OrdIdMap<K, O, T>
285where
286    K: Id,
287    O: Collexetable<T>,
288    T: FieldValue,
289{
290    pub fn iter(&self) -> Iter<'_, K, O, T> {
291        Iter {
292            inner: self.collex.iter(),
293        }
294    }
295}
296
297impl<'a, K, O, T> IntoIterator for &'a OrdIdMap<K, O, T>
298where
299    K: Id,
300    O: Collexetable<T>,
301    T: FieldValue,
302{
303    type Item = &'a O;
304    type IntoIter = Iter<'a, K, O, T>;
305    
306    fn into_iter(self) -> Self::IntoIter {
307        self.iter()
308    }
309}
310
311impl<K, O, T> IntoIterator for OrdIdMap<K, O, T>
312where
313    K: Id,
314    O: Collexetable<T>,
315    T: FieldValue,
316{
317    type Item = O;
318    type IntoIter = IntoIter<K, O, T>;
319    
320    fn into_iter(self) -> Self::IntoIter {
321        IntoIter {
322            inner: self.collex.into_iter(),
323        }
324    }
325}