use std::{
collections::{BTreeMap, HashMap},
convert::TryFrom,
};
use serde::Deserialize;
use crate::{
error::{DittoError, ErrorKind},
prelude::CborValue,
};
#[derive(Debug, Clone, Deserialize)]
#[serde(try_from = "DittoAttachmentTokenStoredFormat")]
pub struct DittoAttachmentToken {
pub(crate) id: Box<[u8]>,
pub(crate) len: u64,
pub(crate) metadata: HashMap<String, String>,
}
impl DittoAttachmentToken {
pub fn id(&self) -> String {
crate::utils::base64_encode_unpadded(&self.id)
}
pub fn len(&self) -> u64 {
self.len
}
pub fn metadata(&self) -> &HashMap<String, String> {
&self.metadata
}
}
impl TryFrom<DittoAttachmentTokenStoredFormat> for DittoAttachmentToken {
type Error = DittoError;
fn try_from(value: DittoAttachmentTokenStoredFormat) -> Result<Self, Self::Error> {
if value._type != (::ffi_sdk::DittoCrdtType::Attachment as u64) {
return Err(ErrorKind::Internal.into());
}
let ret = DittoAttachmentToken {
id: value._id,
len: value._len,
metadata: value._meta,
};
Ok(ret)
}
}
#[derive(Deserialize)]
struct DittoAttachmentTokenStoredFormat {
#[serde(alias = "_ditto_internal_type_jkb12973t4b")]
_type: u64,
#[serde(with = "serde_bytes")]
_id: Box<[u8]>,
_len: u64,
_meta: HashMap<String, String>,
}
pub trait DittoAttachmentTokenLike {
fn parse_attachment_token(self) -> Result<DittoAttachmentToken, DittoError>;
}
impl DittoAttachmentTokenLike for DittoAttachmentToken {
fn parse_attachment_token(self) -> Result<DittoAttachmentToken, DittoError> {
Ok(self)
}
}
impl DittoAttachmentTokenLike for &'_ BTreeMap<CborValue, CborValue> {
fn parse_attachment_token(self) -> Result<DittoAttachmentToken, DittoError> {
#[derive(Deserialize)]
struct DittoAttachmentTokenStoredFormatInQueryResultItem {
id: Box<str>,
len: u64,
metadata: HashMap<String, String>,
}
let DittoAttachmentTokenStoredFormatInQueryResultItem { id, len, metadata } =
::serde_cbor::from_slice(&::serde_cbor::to_vec(self)?)?;
let id = crate::utils::base64_decode_unpadded(&id).map_err(|err| {
DittoError::from_str(
ErrorKind::InvalidInput,
format!("expected base64 `.id` field, got: {err}"),
)
})?;
Ok(DittoAttachmentToken { id, len, metadata })
}
}
impl DittoAttachmentTokenLike for BTreeMap<CborValue, CborValue> {
fn parse_attachment_token(self) -> Result<DittoAttachmentToken, DittoError> {
(&self).parse_attachment_token()
}
}