1pub trait TupleAppend<T> {
4 type Output;
5
6 fn tuple_append(self, right: T) -> Self::Output;
7}
8
9pub trait TupleSize {
10 const SIZE: usize;
11}
12
13#[cfg(not(feature = "std"))]
14pub(crate) mod std_compat {
15 #[cfg(feature = "hashbrown")]
16 pub(crate) type Entry<'a, K, V> =
17 hashbrown::hash_map::Entry<'a, K, V, hashbrown::DefaultHashBuilder>;
18 #[cfg(feature = "hashbrown")]
19 pub(crate) use hashbrown::HashMap;
20
21 #[cfg(not(feature = "hashbrown"))]
34 mod dummy_map {
35 use core::borrow::Borrow;
36
37 pub(crate) struct VecMap<K, V>(alloc::vec::Vec<(K, V)>);
38
39 impl<K, V> Default for VecMap<K, V> {
40 fn default() -> Self {
41 Self(alloc::vec::Vec::new())
42 }
43 }
44
45 impl<K, V> FromIterator<(K, V)> for VecMap<K, V> {
46 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
47 Self(iter.into_iter().collect())
48 }
49 }
50
51 impl<K, V> VecMap<K, V> {
52 pub(crate) fn get<Q>(&self, key: &Q) -> Option<&V>
53 where
54 K: Borrow<Q>,
55 Q: PartialEq,
56 {
57 self.0
58 .iter()
59 .find_map(|(k, v)| (k.borrow() == key).then_some(v))
60 }
61
62 pub(crate) fn entry(&mut self, key: K) -> Entry<'_, K, V>
63 where
64 K: PartialEq,
65 {
66 if let Some(pos) = self.0.iter().position(|(k, _)| *k == key) {
70 Entry::Occupied(OccupiedEntry {
71 entry: &mut self.0[pos],
72 })
73 } else {
74 Entry::Vacant(VacantEntry {
75 vec: &mut self.0,
76 key,
77 })
78 }
79 }
80 }
81
82 #[derive(Debug)]
83 pub struct OccupiedEntry<'a, K, V> {
84 entry: &'a mut (K, V),
85 }
86
87 impl<'a, K, V> OccupiedEntry<'a, K, V> {
88 pub(crate) fn into_mut(self) -> &'a mut V {
89 &mut self.entry.1
90 }
91 }
92
93 #[derive(Debug)]
94 pub struct VacantEntry<'a, K, V> {
95 vec: &'a mut alloc::vec::Vec<(K, V)>,
96 key: K,
97 }
98
99 impl<'a, K, V> VacantEntry<'a, K, V> {
100 pub(crate) fn key(&self) -> &K {
101 &self.key
102 }
103
104 pub(crate) fn insert(self, value: V) -> &'a mut V {
105 let Self { vec, key } = self;
106 vec.push((key, value));
107 &mut vec.last_mut().expect("We literally pushed it above").1
108 }
109 }
110
111 #[derive(Debug)]
112 pub enum Entry<'a, K, V> {
113 Occupied(OccupiedEntry<'a, K, V>),
114 Vacant(VacantEntry<'a, K, V>),
115 }
116 }
117
118 #[cfg(not(feature = "hashbrown"))]
119 pub(crate) use self::dummy_map::VecMap as HashMap;
120 #[cfg(not(feature = "hashbrown"))]
121 pub(crate) type Entry<'a, K, V> = self::dummy_map::Entry<'a, K, V>;
122
123 #[cfg(feature = "__sqlite-shared")]
124 pub(crate) fn catch_unwind<R>(f: impl FnOnce() -> R) -> Result<R, ()> {
125 Ok(f())
126 }
127
128 #[cfg(feature = "__sqlite-shared")]
129 pub(crate) fn panicking() -> bool {
130 false
131 }
132
133 #[cfg(feature = "__sqlite-shared")]
134 pub(crate) fn abort() -> ! {
135 struct DropBomb;
136
137 impl Drop for DropBomb {
138 fn drop(&mut self) {
139 panic!("Abort");
140 }
141 }
142
143 let _guard = DropBomb;
144
145 panic!("Abort");
146 }
147}
148
149#[cfg(feature = "std")]
150pub(crate) mod std_compat {
151 pub(crate) use std::collections::HashMap;
152 #[cfg(any(
154 feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
155 feature = "__sqlite-shared",
156 feature = "mysql",
157 feature = "mariadb",
158 feature = "postgres"
159 ))]
160 pub(crate) use std::collections::hash_map::Entry;
161 #[cfg(feature = "__sqlite-shared")]
162 pub(crate) use std::panic::catch_unwind;
163 #[cfg(feature = "__sqlite-shared")]
164 pub(crate) use std::process::abort;
165 #[cfg(feature = "__sqlite-shared")]
166 pub(crate) use std::thread::panicking;
167}