viceroy_lib/wiggle_abi/
dictionary_impl.rs1use {
4 crate::{
5 error::Error,
6 session::Session,
7 wiggle_abi::{
8 fastly_dictionary::FastlyDictionary,
9 types::{DictionaryHandle, FastlyStatus},
10 },
11 },
12 wiggle::{GuestMemory, GuestPtr},
13};
14
15#[derive(Debug, thiserror::Error)]
16pub enum DictionaryError {
17 #[error("Unknown dictionary item: {0}")]
19 UnknownDictionaryItem(String),
20 #[error("Unknown dictionary: {0}")]
22 UnknownDictionary(String),
23}
24
25impl DictionaryError {
26 pub fn to_fastly_status(&self) -> FastlyStatus {
28 use DictionaryError::*;
29 match self {
30 UnknownDictionaryItem(_) => FastlyStatus::None,
31 UnknownDictionary(_) => FastlyStatus::Badf,
32 }
33 }
34}
35
36impl FastlyDictionary for Session {
37 fn open(
38 &mut self,
39 memory: &mut GuestMemory<'_>,
40 name: GuestPtr<str>,
41 ) -> Result<DictionaryHandle, Error> {
42 self.dictionary_handle(memory.as_str(name)?.ok_or(Error::SharedMemory)?)
43 }
44
45 fn get(
46 &mut self,
47 memory: &mut GuestMemory<'_>,
48 dictionary: DictionaryHandle,
49 key: GuestPtr<str>,
50 buf: GuestPtr<u8>,
51 buf_len: u32,
52 nwritten_out: GuestPtr<u32>,
53 ) -> Result<(), Error> {
54 let dict = &self.dictionary(dictionary)?.contents;
55
56 let item_bytes = {
57 let key = memory.as_str(key)?.ok_or(Error::SharedMemory)?;
58 dict.get(key)
59 .ok_or_else(|| DictionaryError::UnknownDictionaryItem(key.to_owned()))?
60 .as_bytes()
61 };
62
63 if item_bytes.len() > usize::try_from(buf_len).expect("buf_len must fit in usize") {
64 memory.write(nwritten_out, u32::try_from(item_bytes.len()).unwrap_or(0))?;
68 return Err(Error::BufferLengthError {
69 buf: "dictionary_item",
70 len: "dictionary_item_max_len",
71 });
72 }
73
74 let item_len = u32::try_from(item_bytes.len()).unwrap();
76
77 memory.write(nwritten_out, item_len)?;
78 memory.copy_from_slice(item_bytes, buf.as_array(item_len))?;
79
80 Ok(())
81 }
82}