use alloc::boxed::Box;
use super::config::EncoderConfig;
use super::core::cctx::{FrameParams, RequestedParams};
use super::core::cdict::CDict;
use super::internal::requested_params;
use crate::dictionary::{DictionaryContent, DictionaryError, DictionaryId};
#[derive(Copy, Clone, Debug)]
pub struct DictionaryBuilder<'a> {
bytes: &'a [u8],
content: DictionaryContent,
config: EncoderConfig,
}
impl<'a> DictionaryBuilder<'a> {
#[must_use]
pub fn new(bytes: &'a [u8]) -> Self {
Self {
bytes,
content: DictionaryContent::Auto,
config: EncoderConfig::default(),
}
}
#[must_use]
pub const fn with_content(mut self, content: DictionaryContent) -> Self {
self.content = content;
self
}
#[must_use]
pub const fn with_config(mut self, config: EncoderConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<PreparedDictionary, DictionaryError> {
self.config.validate()?;
let requested = requested_params(&self.config);
let cdict = CDict::new(Box::from(self.bytes), self.content, &requested)?;
Ok(PreparedDictionary {
inner: Box::new(Prepared {
#[cfg(feature = "decompression")]
decode: crate::dictionary::decode::parse_decode_parts(self.bytes, self.content)?,
cdict,
config: self.config,
key: dictionary_key(&requested),
}),
})
}
}
pub(crate) fn dictionary_key(requested: &RequestedParams) -> RequestedParams {
RequestedParams {
fparams: FrameParams::default(),
..*requested
}
}
pub struct PreparedDictionary {
inner: Box<Prepared>,
}
struct Prepared {
cdict: CDict,
config: EncoderConfig,
key: RequestedParams,
#[cfg(feature = "decompression")]
decode: crate::dictionary::decode::DecodeParts,
}
impl PreparedDictionary {
#[must_use]
pub const fn id(&self) -> Option<DictionaryId> {
DictionaryId::new(self.inner.cdict.dict_id)
}
#[must_use]
pub const fn config(&self) -> &EncoderConfig {
&self.inner.config
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
self.inner.cdict.bytes()
}
#[must_use]
pub const fn content(&self) -> DictionaryContent {
self.inner.cdict.content()
}
#[must_use]
pub fn retained_bytes(&self) -> usize {
let bytes = self.inner.cdict.retained_bytes();
#[cfg(feature = "decompression")]
let bytes = bytes + self.inner.decode.retained_bytes();
bytes
}
pub(crate) fn cdict(&self) -> &CDict {
&self.inner.cdict
}
#[cfg(feature = "decompression")]
pub(crate) fn decode_view(&self) -> crate::decompressor::DictView<'_> {
self.inner.decode.view(self.inner.cdict.bytes())
}
pub(crate) fn serves(&self, requested: &RequestedParams) -> bool {
dictionary_key(requested) == self.inner.key
}
}
impl core::fmt::Debug for PreparedDictionary {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PreparedDictionary")
.field("id", &self.id())
.field("content", &self.content())
.field("len", &self.as_bytes().len())
.field("config", &self.inner.config)
.finish_non_exhaustive()
}
}
impl AsRef<Self> for PreparedDictionary {
fn as_ref(&self) -> &Self {
self
}
}