Skip to main content

afia_component/
local_storage.rs

1//! Types related to getting and setting values in local storage.
2
3use crate::ComponentImports;
4
5/// An error when attempting to retrieve an value from local storage.
6#[derive(Debug)]
7pub enum LocalStorageGetItemError {
8    /// The key was too long.
9    KeyTooLong,
10    /// The key's bytes were not valid UTF-8.
11    KeyNotUtf8,
12    /// The out buffer was smaller than the length of the input element's value.
13    OutBufferBelowMinimumSize,
14    /// The out buffer was smaller than the length of the local storage item's value.
15    #[allow(missing_docs)]
16    OutBufferSmallerThanValue { value_len: usize },
17    #[allow(missing_docs)]
18    Unrecognized { error_code: i32 },
19}
20
21impl ComponentImports {
22    /// Get an item from local storage.
23    pub fn local_storage_get_item<'out>(
24        &self,
25        key: &str,
26        out_buffer: &'out mut [u8],
27    ) -> Result<Option<&'out str>, LocalStorageGetItemError> {
28        let returned = unsafe {
29            afia_component_sys::local_storage_get_item(
30                self.component_imports_ptr,
31                key.as_ptr(),
32                key.len(),
33                out_buffer.as_mut_ptr(),
34                out_buffer.len(),
35            )
36        };
37
38        match returned {
39            length if length >= 0 => {
40                let length = length as usize;
41
42                // SAFETY: here we are trusting that the Afia host worked as expected and wrote a
43                // utf8 string to the buffer.
44                let string = unsafe { std::str::from_utf8_unchecked(&out_buffer[0..length]) };
45
46                Ok(Some(string))
47            }
48            -1 => Err(LocalStorageGetItemError::KeyTooLong),
49            -2 => Err(LocalStorageGetItemError::KeyNotUtf8),
50            -3 => Ok(None),
51            -4 => Err(LocalStorageGetItemError::OutBufferBelowMinimumSize),
52            -5 => {
53                let mut val_len = [0; 4];
54                val_len.copy_from_slice(&out_buffer[0..4]);
55                let val = i32::from_le_bytes(val_len);
56                Err(LocalStorageGetItemError::OutBufferSmallerThanValue {
57                    value_len: val as usize,
58                })
59            }
60            unknown_error_code => Err(LocalStorageGetItemError::Unrecognized {
61                error_code: unknown_error_code,
62            }),
63        }
64    }
65
66    /// Set an item in local storage.
67    pub fn local_storage_set_item(&self, key: &str, val: &str) {
68        unsafe {
69            afia_component_sys::local_storage_set_item(
70                self.component_imports_ptr,
71                key.as_ptr(),
72                key.len(),
73                val.as_ptr(),
74                val.len(),
75            )
76        }
77    }
78}