#![deprecated(since = "0.8.6", note = "renamed to `handle::config_store`")]
#[cfg(not(target_env = "p1"))]
use fastly_sys::service0_1_0::fastly::compute as wit;
#[cfg(target_env = "p1")]
use {crate::abi, fastly_shared::FastlyStatus};
#[derive(Debug)]
#[cfg_attr(target_env = "p1", derive(Eq, Hash, PartialEq))]
#[repr(transparent)]
#[deprecated(since = "0.8.6", note = "renamed to `ConfigStoreHandle`")]
pub struct DictionaryHandle {
#[cfg(target_env = "p1")]
handle: u32,
#[cfg(not(target_env = "p1"))]
handle: wit::dictionary::Dictionary,
}
impl DictionaryHandle {
#[deprecated(
since = "0.8.6",
note = "use the constant in `ConfigStoreHandle` instead"
)]
#[cfg(target_env = "p1")]
pub const INVALID: Self = DictionaryHandle {
handle: fastly_shared::INVALID_DICTIONARY_HANDLE,
};
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
pub fn open(name: &str) -> Result<Self, OpenError> {
use OpenError::*;
#[cfg(target_env = "p1")]
{
let mut handle = Self::INVALID;
unsafe { abi::fastly_dictionary::open(name.as_ptr(), name.len(), handle.as_u32_mut()) }
.result()
.map(|_| handle)
.map_err(|status| match status {
FastlyStatus::NONE => NameEmpty,
FastlyStatus::UNSUPPORTED => NameTooLong,
FastlyStatus::INVAL => NameInvalid,
FastlyStatus::BADF => DictionaryDoesNotExist,
_ => panic!("fastly_dictionary::open returned an unrecognized result"),
})
}
#[cfg(not(target_env = "p1"))]
{
let handle = wit::dictionary::Dictionary::open(name).map_err(|err| match err {
wit::types::OpenError::NameTooLong => NameTooLong,
wit::types::OpenError::InvalidSyntax if name.is_empty() => NameEmpty,
wit::types::OpenError::InvalidSyntax => NameInvalid,
wit::types::OpenError::NotFound => DictionaryDoesNotExist,
_ => panic!("dictionary::Dictionary::open returned an unrecognized result"),
})?;
Ok(Self { handle })
}
}
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
pub fn get(&self, key: &str, max_len: usize) -> Result<Option<String>, LookupError> {
#[cfg(target_env = "p1")]
{
#[cfg(target_env = "p1")]
if self.is_invalid() {
panic!("cannot lookup value with invalid dictionary handle");
}
let mut buf = bytes::BytesMut::with_capacity(max_len);
let mut nwritten = 0;
let status = unsafe {
abi::fastly_dictionary::get(
self.as_u32(),
key.as_ptr(),
key.len(),
buf.as_mut_ptr(),
buf.capacity(),
&mut nwritten,
)
};
match status.result().map(|_| nwritten) {
Ok(nwritten) => {
assert!(
nwritten <= buf.capacity(),
"fastly_dictionary::get wrote too many bytes"
);
unsafe {
buf.set_len(nwritten);
}
Ok(Some(
String::from_utf8(Vec::from(buf)).expect("host returns valid UTF-8"),
))
}
Err(FastlyStatus::NONE) => Ok(None),
Err(FastlyStatus::ERROR) => Err(LookupError::Other),
Err(FastlyStatus::BADF) => Err(LookupError::DictionaryInvalid),
Err(FastlyStatus::INVAL) => Err(LookupError::KeyInvalid),
Err(FastlyStatus::UNSUPPORTED) => Err(LookupError::KeyTooLong),
Err(FastlyStatus::BUFLEN) => Err(LookupError::ValueTooLong),
Err(FastlyStatus::LIMITEXCEEDED) => Err(LookupError::TooManyLookups),
Err(_) => panic!("fastly_dictionary::get returned an unrecognized result"),
}
}
#[cfg(not(target_env = "p1"))]
{
match self.handle.lookup(key, max_len as u64) {
Ok(val) => Ok(val),
Err(wit::types::Error::GenericError) => Err(LookupError::Other),
Err(wit::types::Error::InvalidArgument) => Err(LookupError::KeyInvalid),
Err(wit::types::Error::Unsupported) => Err(LookupError::KeyTooLong),
Err(wit::types::Error::BufferLen(_)) => Err(LookupError::ValueTooLong),
Err(wit::types::Error::LimitExceeded) => Err(LookupError::TooManyLookups),
Err(_) => panic!("dictionary::Dictionary::get returned an unrecognized result"),
}
}
}
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
pub fn contains(&self, key: &str) -> Result<bool, LookupError> {
use LookupError::*;
match self.get(key, 0) {
Ok(Some(_)) | Err(ValueTooLong) => Ok(true),
Ok(None) => Ok(false),
Err(e) => Err(e),
}
}
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
#[cfg(target_env = "p1")]
pub fn is_valid(&self) -> bool {
!self.is_invalid()
}
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
#[cfg(target_env = "p1")]
pub fn is_invalid(&self) -> bool {
self.handle == Self::INVALID.handle
}
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
#[cfg(target_env = "p1")]
pub(crate) fn as_u32(&self) -> u32 {
self.handle
}
#[deprecated(
since = "0.8.6",
note = "use the method on `ConfigStoreHandle` instead"
)]
#[cfg(target_env = "p1")]
pub(crate) fn as_u32_mut(&mut self) -> &mut u32 {
&mut self.handle
}
}
#[derive(Debug, thiserror::Error)]
#[deprecated(since = "0.8.6", note = "use `config_store::OpenError` instead")]
#[non_exhaustive]
pub enum OpenError {
#[error("dictionary could not be found")]
DictionaryDoesNotExist,
#[error("dictionary names cannot be empty")]
NameEmpty,
#[error("dictionary name too long")]
NameTooLong,
#[error("invalid dictionary name")]
NameInvalid,
}
#[derive(Debug, thiserror::Error)]
#[deprecated(since = "0.8.6", note = "use `config_store::LookupError` instead")]
#[non_exhaustive]
pub enum LookupError {
#[error("invalid dictionary")]
DictionaryInvalid,
#[error("invalid dictionary key")]
KeyInvalid,
#[error("dictionary keys must be shorter than 256 characters")]
KeyTooLong,
#[error("dictionary value was longer than the given buffer")]
ValueTooLong,
#[error("Too many lookups have been performed")]
TooManyLookups,
#[error("dictionary lookup failed")]
Other,
}