xref: /aosp_15_r20/bootable/libbootloader/gbl/smoltcp/heapless.rs (revision 5225e6b173e52d2efc6bcf950c27374fd72adabc)
1*5225e6b1SAndroid Build Coastguard Worker // Copyright 2024, The Android Open Source Project
2*5225e6b1SAndroid Build Coastguard Worker //
3*5225e6b1SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*5225e6b1SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*5225e6b1SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*5225e6b1SAndroid Build Coastguard Worker //
7*5225e6b1SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*5225e6b1SAndroid Build Coastguard Worker //
9*5225e6b1SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*5225e6b1SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*5225e6b1SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*5225e6b1SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*5225e6b1SAndroid Build Coastguard Worker // limitations under the License.
14*5225e6b1SAndroid Build Coastguard Worker 
15*5225e6b1SAndroid Build Coastguard Worker //! Selective implementation of APIs from crate `heapless` 0.8.0 using alloc.
16*5225e6b1SAndroid Build Coastguard Worker //! https://docs.rs/heapless/0.8.0/heapless/index.html
17*5225e6b1SAndroid Build Coastguard Worker //!
18*5225e6b1SAndroid Build Coastguard Worker //! The smoltcp crate depends on crate heapless. At the time this is written, the crate is either
19*5225e6b1SAndroid Build Coastguard Worker //! still in the process of being imported to Android or abandoned. Since we only use them in the
20*5225e6b1SAndroid Build Coastguard Worker //! EFI build which has alloc, we use a naive implementation of the needed APIs using heap
21*5225e6b1SAndroid Build Coastguard Worker //! allocation as a workaround for now.
22*5225e6b1SAndroid Build Coastguard Worker 
23*5225e6b1SAndroid Build Coastguard Worker #![no_std]
24*5225e6b1SAndroid Build Coastguard Worker #![no_main]
25*5225e6b1SAndroid Build Coastguard Worker 
26*5225e6b1SAndroid Build Coastguard Worker use core::ops::{Deref, DerefMut};
27*5225e6b1SAndroid Build Coastguard Worker 
28*5225e6b1SAndroid Build Coastguard Worker extern crate alloc;
29*5225e6b1SAndroid Build Coastguard Worker use alloc::collections::BTreeMap;
30*5225e6b1SAndroid Build Coastguard Worker use alloc::vec::Vec as AllocVec;
31*5225e6b1SAndroid Build Coastguard Worker 
32*5225e6b1SAndroid Build Coastguard Worker /// `heapless::Vec`
33*5225e6b1SAndroid Build Coastguard Worker #[derive(Debug, PartialEq, Eq, Clone)]
34*5225e6b1SAndroid Build Coastguard Worker pub struct Vec<T, const N: usize>(AllocVec<T>);
35*5225e6b1SAndroid Build Coastguard Worker 
36*5225e6b1SAndroid Build Coastguard Worker impl<T, const N: usize> Vec<T, N> {
new() -> Self37*5225e6b1SAndroid Build Coastguard Worker     pub fn new() -> Self {
38*5225e6b1SAndroid Build Coastguard Worker         Self(AllocVec::new())
39*5225e6b1SAndroid Build Coastguard Worker     }
40*5225e6b1SAndroid Build Coastguard Worker 
capacity(&self) -> usize41*5225e6b1SAndroid Build Coastguard Worker     pub fn capacity(&self) -> usize {
42*5225e6b1SAndroid Build Coastguard Worker         N
43*5225e6b1SAndroid Build Coastguard Worker     }
44*5225e6b1SAndroid Build Coastguard Worker 
push(&mut self, item: T) -> Result<(), T>45*5225e6b1SAndroid Build Coastguard Worker     pub fn push(&mut self, item: T) -> Result<(), T> {
46*5225e6b1SAndroid Build Coastguard Worker         match self.0.len() < N {
47*5225e6b1SAndroid Build Coastguard Worker             true => {
48*5225e6b1SAndroid Build Coastguard Worker                 self.0.push(item);
49*5225e6b1SAndroid Build Coastguard Worker                 Ok(())
50*5225e6b1SAndroid Build Coastguard Worker             }
51*5225e6b1SAndroid Build Coastguard Worker             _ => Err(item),
52*5225e6b1SAndroid Build Coastguard Worker         }
53*5225e6b1SAndroid Build Coastguard Worker     }
54*5225e6b1SAndroid Build Coastguard Worker }
55*5225e6b1SAndroid Build Coastguard Worker 
56*5225e6b1SAndroid Build Coastguard Worker impl<T, const N: usize> Deref for Vec<T, N> {
57*5225e6b1SAndroid Build Coastguard Worker     type Target = AllocVec<T>;
58*5225e6b1SAndroid Build Coastguard Worker 
deref(&self) -> &Self::Target59*5225e6b1SAndroid Build Coastguard Worker     fn deref(&self) -> &Self::Target {
60*5225e6b1SAndroid Build Coastguard Worker         &self.0
61*5225e6b1SAndroid Build Coastguard Worker     }
62*5225e6b1SAndroid Build Coastguard Worker }
63*5225e6b1SAndroid Build Coastguard Worker 
64*5225e6b1SAndroid Build Coastguard Worker impl<T, const N: usize> DerefMut for Vec<T, N> {
deref_mut(&mut self) -> &mut Self::Target65*5225e6b1SAndroid Build Coastguard Worker     fn deref_mut(&mut self) -> &mut Self::Target {
66*5225e6b1SAndroid Build Coastguard Worker         &mut self.0
67*5225e6b1SAndroid Build Coastguard Worker     }
68*5225e6b1SAndroid Build Coastguard Worker }
69*5225e6b1SAndroid Build Coastguard Worker 
70*5225e6b1SAndroid Build Coastguard Worker impl<'a, T, const N: usize> IntoIterator for &'a Vec<T, N> {
71*5225e6b1SAndroid Build Coastguard Worker     type Item = &'a T;
72*5225e6b1SAndroid Build Coastguard Worker     type IntoIter = core::slice::Iter<'a, T>;
73*5225e6b1SAndroid Build Coastguard Worker 
into_iter(self) -> Self::IntoIter74*5225e6b1SAndroid Build Coastguard Worker     fn into_iter(self) -> Self::IntoIter {
75*5225e6b1SAndroid Build Coastguard Worker         self.0.iter()
76*5225e6b1SAndroid Build Coastguard Worker     }
77*5225e6b1SAndroid Build Coastguard Worker }
78*5225e6b1SAndroid Build Coastguard Worker 
79*5225e6b1SAndroid Build Coastguard Worker /// `heapless::LinearMap`
80*5225e6b1SAndroid Build Coastguard Worker #[derive(Debug, PartialEq, Eq, Clone)]
81*5225e6b1SAndroid Build Coastguard Worker pub struct LinearMap<K, V, const N: usize>(BTreeMap<K, V>);
82*5225e6b1SAndroid Build Coastguard Worker 
83*5225e6b1SAndroid Build Coastguard Worker impl<K: core::cmp::Ord, V, const N: usize> LinearMap<K, V, N> {
new() -> Self84*5225e6b1SAndroid Build Coastguard Worker     pub fn new() -> Self {
85*5225e6b1SAndroid Build Coastguard Worker         Self(BTreeMap::new())
86*5225e6b1SAndroid Build Coastguard Worker     }
87*5225e6b1SAndroid Build Coastguard Worker 
capacity(&self) -> usize88*5225e6b1SAndroid Build Coastguard Worker     pub fn capacity(&self) -> usize {
89*5225e6b1SAndroid Build Coastguard Worker         N
90*5225e6b1SAndroid Build Coastguard Worker     }
91*5225e6b1SAndroid Build Coastguard Worker 
insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)>92*5225e6b1SAndroid Build Coastguard Worker     pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)> {
93*5225e6b1SAndroid Build Coastguard Worker         match self.0.len() < N {
94*5225e6b1SAndroid Build Coastguard Worker             true => Ok(self.0.insert(key, value)),
95*5225e6b1SAndroid Build Coastguard Worker             _ => Err((key, value)),
96*5225e6b1SAndroid Build Coastguard Worker         }
97*5225e6b1SAndroid Build Coastguard Worker     }
98*5225e6b1SAndroid Build Coastguard Worker }
99*5225e6b1SAndroid Build Coastguard Worker 
100*5225e6b1SAndroid Build Coastguard Worker impl<K, V, const N: usize> Deref for LinearMap<K, V, N> {
101*5225e6b1SAndroid Build Coastguard Worker     type Target = BTreeMap<K, V>;
102*5225e6b1SAndroid Build Coastguard Worker 
deref(&self) -> &Self::Target103*5225e6b1SAndroid Build Coastguard Worker     fn deref(&self) -> &Self::Target {
104*5225e6b1SAndroid Build Coastguard Worker         &self.0
105*5225e6b1SAndroid Build Coastguard Worker     }
106*5225e6b1SAndroid Build Coastguard Worker }
107*5225e6b1SAndroid Build Coastguard Worker 
108*5225e6b1SAndroid Build Coastguard Worker impl<K, V, const N: usize> DerefMut for LinearMap<K, V, N> {
deref_mut(&mut self) -> &mut Self::Target109*5225e6b1SAndroid Build Coastguard Worker     fn deref_mut(&mut self) -> &mut Self::Target {
110*5225e6b1SAndroid Build Coastguard Worker         &mut self.0
111*5225e6b1SAndroid Build Coastguard Worker     }
112*5225e6b1SAndroid Build Coastguard Worker }
113