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