templar_vault_kernel/types/
mod.rs1#[cfg(feature = "schemars")]
6use alloc::borrow::ToOwned;
7#[cfg(feature = "borsh-schema")]
8use alloc::string::ToString;
9
10use derive_more::{Display, From, Into};
11
12#[repr(transparent)]
14#[templar_vault_macros::vault_derive(borsh, borsh_schema, serde, postcard, schemars)]
15#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, From, Into, Display)]
16#[display("{_0}")]
17pub struct TimestampNs(pub u64);
18
19#[repr(transparent)]
20#[templar_vault_macros::vault_derive(borsh, borsh_schema, serde, postcard, schemars)]
21#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, From, Into, Display)]
22#[display("{_0}")]
23pub struct DurationNs(pub u64);
24
25impl TimestampNs {
26 pub const ZERO: Self = Self(0);
27
28 pub const fn from_nanos(nanos: u64) -> Self {
30 Self(nanos)
31 }
32
33 pub const fn as_u64(self) -> u64 {
35 self.0
36 }
37
38 pub const fn saturating_add(self, rhs: Self) -> Self {
40 Self(self.0.saturating_add(rhs.0))
41 }
42
43 pub const fn saturating_add_u64(self, rhs: u64) -> Self {
45 Self(self.0.saturating_add(rhs))
46 }
47
48 pub const fn saturating_sub(self, rhs: Self) -> Self {
50 Self(self.0.saturating_sub(rhs.0))
51 }
52
53 pub const fn saturating_add_duration(self, rhs: DurationNs) -> Self {
54 Self(self.0.saturating_add(rhs.0))
55 }
56}
57
58impl DurationNs {
59 pub const ZERO: Self = Self(0);
60
61 pub const fn from_nanos(nanos: u64) -> Self {
62 Self(nanos)
63 }
64
65 pub const fn as_u64(self) -> u64 {
67 self.0
68 }
69}
70
71#[repr(transparent)]
73#[templar_vault_macros::vault_derive(borsh, borsh_schema, serde, postcard, schemars)]
74#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, From, Into, Display)]
75#[display("{_0}")]
76pub struct ExpectedIdx(pub u32);
77
78#[repr(transparent)]
80#[templar_vault_macros::vault_derive(borsh, borsh_schema, serde, postcard, schemars)]
81#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, From, Into, Display)]
82#[display("{_0}")]
83pub struct ActualIdx(pub u32);
84
85#[repr(transparent)]
88#[templar_vault_macros::vault_derive(borsh, borsh_schema, schemars)]
89#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, From, Into)]
90pub struct Address(pub [u8; 32]);
91
92impl Address {
93 pub const fn from_bytes(bytes: [u8; 32]) -> Self {
95 Self(bytes)
96 }
97
98 pub const fn as_bytes(&self) -> &[u8; 32] {
100 &self.0
101 }
102}
103
104impl AsRef<[u8; 32]> for Address {
105 fn as_ref(&self) -> &[u8; 32] {
106 &self.0
107 }
108}
109
110impl AsRef<[u8]> for Address {
111 fn as_ref(&self) -> &[u8] {
112 &self.0
113 }
114}
115
116#[cfg(all(feature = "serde", not(feature = "postcard")))]
117mod address_serde_impl {
118 use super::*;
119 use serde::de;
120 use serde::{Deserialize, Deserializer, Serialize, Serializer};
121
122 impl Serialize for Address {
123 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
124 where
125 S: Serializer,
126 {
127 serializer.serialize_bytes(&self.0)
128 }
129 }
130
131 impl<'de> Deserialize<'de> for Address {
132 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133 where
134 D: Deserializer<'de>,
135 {
136 struct AddressVisitor;
137
138 impl<'de> de::Visitor<'de> for AddressVisitor {
139 type Value = Address;
140
141 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
142 formatter.write_str("exactly 32 bytes for Address")
143 }
144
145 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
146 where
147 E: de::Error,
148 {
149 let bytes: [u8; 32] = v
150 .try_into()
151 .map_err(|_| E::custom("expected exactly 32 bytes for Address"))?;
152 Ok(Address(bytes))
153 }
154
155 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
156 where
157 A: de::SeqAccess<'de>,
158 {
159 let mut bytes = [0u8; 32];
160 for byte in &mut bytes {
161 *byte = seq.next_element()?.ok_or_else(|| {
162 de::Error::custom("expected exactly 32 bytes for Address")
163 })?;
164 }
165
166 if seq.next_element::<u8>()?.is_some() {
167 return Err(de::Error::custom("expected exactly 32 bytes for Address"));
168 }
169
170 Ok(Address(bytes))
171 }
172 }
173
174 deserializer.deserialize_bytes(AddressVisitor)
175 }
176 }
177}
178
179#[cfg(feature = "postcard")]
180mod address_postcard_serde_impl {
181 use super::*;
182 #[cfg(not(feature = "soroban"))]
183 use serde::de;
184 use serde::{Deserialize, Deserializer, Serialize, Serializer};
185
186 impl Serialize for Address {
187 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
188 where
189 S: Serializer,
190 {
191 #[cfg(feature = "soroban")]
192 {
193 self.0.serialize(serializer)
194 }
195
196 #[cfg(not(feature = "soroban"))]
197 {
198 serializer.serialize_bytes(&self.0)
199 }
200 }
201 }
202
203 impl<'de> Deserialize<'de> for Address {
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: Deserializer<'de>,
207 {
208 #[cfg(feature = "soroban")]
209 {
210 <[u8; 32]>::deserialize(deserializer).map(Address)
211 }
212
213 #[cfg(not(feature = "soroban"))]
214 {
215 struct AddressVisitor;
216
217 impl<'de> de::Visitor<'de> for AddressVisitor {
218 type Value = Address;
219
220 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
221 formatter.write_str("exactly 32 bytes for Address")
222 }
223
224 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
225 where
226 E: de::Error,
227 {
228 let bytes: [u8; 32] = v
229 .try_into()
230 .map_err(|_| E::custom("expected exactly 32 bytes for Address"))?;
231 Ok(Address(bytes))
232 }
233
234 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
235 where
236 A: de::SeqAccess<'de>,
237 {
238 let mut bytes = [0u8; 32];
239 for byte in &mut bytes {
240 *byte = seq.next_element()?.ok_or_else(|| {
241 de::Error::custom("expected exactly 32 bytes for Address")
242 })?;
243 }
244
245 if seq.next_element::<u8>()?.is_some() {
246 return Err(de::Error::custom("expected exactly 32 bytes for Address"));
247 }
248
249 Ok(Address(bytes))
250 }
251 }
252
253 deserializer.deserialize_bytes(AddressVisitor)
254 }
255 }
256 }
257}
258
259#[templar_vault_macros::vault_derive(borsh, serde, postcard)]
263#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, From, Into)]
264pub struct AssetId(pub [u8; 32]);
265
266impl AssetId {
267 pub const fn from_bytes(bytes: [u8; 32]) -> Self {
269 Self(bytes)
270 }
271
272 pub const fn as_bytes(&self) -> &[u8; 32] {
274 &self.0
275 }
276}
277
278impl AsRef<[u8; 32]> for AssetId {
279 fn as_ref(&self) -> &[u8; 32] {
280 &self.0
281 }
282}
283
284impl AsRef<[u8]> for AssetId {
285 fn as_ref(&self) -> &[u8] {
286 &self.0
287 }
288}
289
290#[templar_vault_macros::vault_derive(borsh, serde, postcard)]
292#[derive(Clone, Copy, PartialEq, Eq)]
293pub struct EscrowSettlement {
294 pub to_burn: u128,
296 pub refund: u128,
298}
299
300impl EscrowSettlement {
301 pub fn from_escrow_and_burn(escrow_shares: u128, burn_shares: u128) -> Self {
305 let to_burn = burn_shares.min(escrow_shares);
306 let refund = escrow_shares.saturating_sub(to_burn);
307 Self { to_burn, refund }
308 }
309
310 pub fn burn_all(shares: u128) -> Self {
312 Self {
313 to_burn: shares,
314 refund: 0,
315 }
316 }
317
318 pub fn refund_all(shares: u128) -> Self {
320 Self {
321 to_burn: 0,
322 refund: shares,
323 }
324 }
325
326 pub fn partial(to_burn: u128, refund: u128) -> Self {
328 Self { to_burn, refund }
329 }
330}
331
332#[templar_vault_macros::vault_derive(borsh, serde, postcard)]
334#[derive(Clone, Copy, PartialEq, Eq, From, Into)]
335pub struct KernelVersion(pub u32);
336
337#[cfg(test)]
338mod tests;