thruput_sdk/storage/bytestring.rs
1use super::keypath::{Keypath, LeafKey};
2use crate::sys_exn::bytestring::*;
3use core::fmt::Debug;
4
5#[derive(Debug)]
6pub struct Bytestring {
7 key: LeafKey,
8}
9
10impl From<Keypath> for Bytestring {
11 fn from(keypath: Keypath) -> Self {
12 Self {
13 key: LeafKey::from(keypath),
14 }
15 }
16}
17
18impl Bytestring {
19 /// Returns the number of bytes stored at this key.
20 ///
21 /// **Aborts** the transaction (throws a syscall exception) if nothing is
22 /// stored here, or if a value of another type occupies the key. Use
23 /// [`exists`](Self::exists) to test for presence without aborting, or
24 /// [`try_get`](Self::try_get) to read an optional value.
25 pub fn len(&self) -> usize {
26 bytestring_get_len(&self.key) as usize
27 }
28
29 /// Returns `true` if the stored bytestring has zero length (`len() == 0`).
30 ///
31 /// Shares [`len`](Self::len)'s abort behavior exactly: this **aborts** the
32 /// transaction on a never-set key rather than reporting "empty". An empty
33 /// bytestring and a missing key are distinct states here — use
34 /// [`exists`](Self::exists) to tell them apart without aborting. (This
35 /// differs deliberately from [`Vector::is_empty`](super::vector::Vector::is_empty),
36 /// which treats a never-set vector as empty.)
37 pub fn is_empty(&self) -> bool {
38 self.len() == 0
39 }
40
41 /// Returns `true` if a bytestring is stored at this key, `false` if nothing
42 /// is.
43 ///
44 /// Unlike [`len`](Self::len)/[`is_empty`](Self::is_empty)/[`get`](Self::get)/[`get_sized`](Self::get_sized),
45 /// this does not abort on a missing key — it is the way to distinguish a
46 /// missing key from a present-but-empty bytestring. (It still throws if a
47 /// value of another type occupies the key.)
48 pub fn exists(&self) -> bool {
49 bytestring_exists(&self.key)
50 }
51
52 /// Stores `buf` at this key, overwriting any existing value (including one
53 /// of another type). If this key's keypath is exclusive, the write then
54 /// requests an exclusive lock; otherwise the key's storage flags stay as
55 /// they are.
56 pub fn set(&mut self, buf: &[u8]) {
57 if self.key.is_exclusive() {
58 bytestring_set_exclusive(&self.key, buf);
59 } else {
60 bytestring_set(&self.key, buf);
61 }
62 }
63
64 /// Reads the stored bytestring into a fixed-size array.
65 ///
66 /// **Aborts** if the key is missing, holds a value of another type, or
67 /// holds a bytestring whose length is not exactly `N`
68 /// (`LibraryExn::BytestringWrongSize`). Beware that large `N` may overflow
69 /// the execution stack.
70 pub fn get_sized<const N: usize>(&self) -> [u8; N] {
71 bytestring_get_sized(&self.key)
72 }
73
74 /// Reads the stored bytestring.
75 ///
76 /// **Aborts** if the key is missing or holds a value of another type. Use
77 /// [`try_get`](Self::try_get) to handle those cases gracefully.
78 #[cfg(feature = "alloc")]
79 pub fn get(&self) -> alloc::boxed::Box<[u8]> {
80 bytestring_get(&self.key)
81 }
82
83 /// Reads the stored bytestring, reporting failure as `Err` instead of
84 /// aborting (the `try_` law; see the [`exn`](mod@crate::exn) module
85 /// docs).
86 ///
87 /// A missing key is an `Err` for which
88 /// [`is_storage_missing`](crate::exn::LibraryExn::is_storage_missing)
89 /// is true — use
90 /// [`none_if_missing`](crate::exn::NoneIfMissing::none_if_missing) to
91 /// treat just that case as an ordinary `None`. A value of another
92 /// storage type or any other syscall failure is a `LibraryExn::Syscall`.
93 #[cfg(feature = "alloc")]
94 pub fn try_get(
95 &self,
96 ) -> Result<alloc::boxed::Box<[u8]>, crate::exn::LibraryExn> {
97 bytestring_try_get(&self.key)
98 }
99}
100
101impl super::sealed::Sealed for Bytestring {}
102impl super::node::StorageType for Bytestring {}
103
104impl super::flags::Flaggable for Bytestring {
105 fn storage_key(&self) -> &crate::types::StorageKey {
106 self.key.get()
107 }
108}
109
110impl super::deletable::Deletable for Bytestring {
111 fn delete_internal(&mut self, exclusive: bool) {
112 let exclusive = exclusive || self.key.is_exclusive();
113 crate::sys_exn::delete::delete(self.key.get(), exclusive);
114 }
115}