1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use fastly_shared::{FastlyStatus, INVALID_BODY_HANDLE, INVALID_OBJECT_STORE_HANDLE};
use fastly_sys::fastly_object_store as sys;
use crate::handle::BodyHandle;
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum ObjectStoreError {
#[error("Invalid Object Store key")]
InvalidKey,
#[error("Invalid Object Store handle")]
InvalidObjectStoreHandle,
#[error("Object Store {0:?} not found")]
ObjectStoreNotFound(String),
#[error("Unexpected Object Store error: {0:?}")]
Unexpected(FastlyStatus),
}
impl From<FastlyStatus> for ObjectStoreError {
fn from(st: FastlyStatus) -> Self {
ObjectStoreError::Unexpected(st)
}
}
#[derive(Debug, Eq, Hash, PartialEq)]
#[repr(transparent)]
pub struct StoreHandle {
handle: u32,
}
impl StoreHandle {
pub fn as_u32(&self) -> u32 {
self.handle
}
pub fn open(name: &str) -> Result<Option<StoreHandle>, ObjectStoreError> {
let mut store_handle_out = INVALID_OBJECT_STORE_HANDLE;
let status = unsafe { sys::open(name.as_ptr(), name.len(), &mut store_handle_out) };
status.result().map_err(|st| match st {
FastlyStatus::INVAL => ObjectStoreError::ObjectStoreNotFound(name.to_owned()),
_ => st.into(),
})?;
if store_handle_out == INVALID_OBJECT_STORE_HANDLE {
Ok(None)
} else {
Ok(Some(StoreHandle {
handle: store_handle_out,
}))
}
}
pub fn lookup(&self, key: impl AsRef<[u8]>) -> Result<Option<BodyHandle>, ObjectStoreError> {
let mut body_handle_out = INVALID_BODY_HANDLE;
let key = key.as_ref();
let status =
unsafe { sys::lookup(self.as_u32(), key.as_ptr(), key.len(), &mut body_handle_out) };
status.result().map_err(|st| match st {
FastlyStatus::BADF => ObjectStoreError::InvalidObjectStoreHandle,
FastlyStatus::INVAL => ObjectStoreError::InvalidKey,
_ => st.into(),
})?;
if body_handle_out == INVALID_BODY_HANDLE {
Ok(None)
} else {
Ok(Some(unsafe { BodyHandle::from_u32(body_handle_out) }))
}
}
pub fn insert(
&mut self,
key: impl AsRef<str>,
value: BodyHandle,
) -> Result<(), ObjectStoreError> {
let key = key.as_ref();
let status =
unsafe { sys::insert(self.as_u32(), key.as_ptr(), key.len(), value.into_u32()) };
status.result().map_err(|st| match st {
FastlyStatus::BADF => ObjectStoreError::InvalidObjectStoreHandle,
FastlyStatus::INVAL => ObjectStoreError::InvalidKey,
_ => st.into(),
})?;
Ok(())
}
}