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 = (K, &'a O);
242    
243    fn next(&mut self) -> Option<Self::Item> {
244        self.inner.next().map(|pair| (pair.0, &pair.1))
245    }
246    
247    fn size_hint(&self) -> (usize, Option<usize>) {
248        self.inner.size_hint()
249    }
250}
251
252pub struct IntoIter<K, O, T>
253where
254    K: Id,
255    O: Collexetable<T>,
256    T: FieldValue,
257{
258    inner: CollexIntoIter<Pair<K, O>, T>,
259}
260
261impl<K, O, T> Iterator for IntoIter<K, O, T>
262where
263    K: Id,
264    O: Collexetable<T>,
265    T: FieldValue,
266{
267    type Item = (K, O);
268    
269    fn next(&mut self) -> Option<Self::Item> {
270        self.inner.next().map(|pair| (pair.0, pair.1))
271    }
272    
273    fn size_hint(&self) -> (usize, Option<usize>) {
274        self.inner.size_hint()
275    }
276}
277
278pub struct Keys<'a, K: Id, O: Collexetable<T>, T: FieldValue> {
279    inner: CollexIter<'a, Pair<K, O>, T>,
280}
281
282impl<K, O, T> OrdIdMap<K, O, T>
283where
284    K: Id,
285    O: Collexetable<T>,
286    T: FieldValue,
287{
288    pub fn iter(&self) -> Iter<'_, K, O, T> {
289        Iter {
290            inner: self.collex.iter(),
291        }
292    }
293}
294
295impl<'a, K, O, T> IntoIterator for &'a OrdIdMap<K, O, T>
296where
297    K: Id,
298    O: Collexetable<T>,
299    T: FieldValue,
300{
301    type Item = (K, &'a O);
302    type IntoIter = Iter<'a, K, O, T>;
303    
304    fn into_iter(self) -> Self::IntoIter {
305        self.iter()
306    }
307}
308
309impl<K, O, T> IntoIterator for OrdIdMap<K, O, T>
310where
311    K: Id,
312    O: Collexetable<T>,
313    T: FieldValue,
314{
315    type Item = (K, O);
316    type IntoIter = IntoIter<K, O, T>;
317    
318    fn into_iter(self) -> Self::IntoIter {
319        IntoIter {
320            inner: self.collex.into_iter(),
321        }
322    }
323}