use std::{
borrow::{Borrow, Cow},
convert::TryFrom,
ops::Deref,
};
use serde::{Deserialize, Serialize};
use crate::Document;
use super::{Error, ErrorKind, Iter, RawBson, RawDocument, Result};
#[derive(Clone, PartialEq)]
pub struct RawDocumentBuf {
data: Vec<u8>,
}
impl RawDocumentBuf {
pub fn new(data: Vec<u8>) -> Result<RawDocumentBuf> {
let _ = RawDocument::new(data.as_slice())?;
Ok(Self { data })
}
pub fn from_document(doc: &Document) -> Result<RawDocumentBuf> {
let mut data = Vec::new();
doc.to_writer(&mut data).map_err(|e| Error {
key: None,
kind: ErrorKind::MalformedValue {
message: e.to_string(),
},
})?;
Ok(Self { data })
}
pub fn iter(&self) -> Iter<'_> {
self.into_iter()
}
pub fn into_vec(self) -> Vec<u8> {
self.data
}
}
impl<'de> Deserialize<'de> for RawDocumentBuf {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let doc: &'de RawDocument = Deserialize::deserialize(deserializer)?;
Ok(doc.to_owned())
}
}
impl Serialize for RawDocumentBuf {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let doc: &RawDocument = self.deref();
doc.serialize(serializer)
}
}
impl std::fmt::Debug for RawDocumentBuf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RawDocumentBuf")
.field("data", &hex::encode(&self.data))
.finish()
}
}
impl<'a> From<RawDocumentBuf> for Cow<'a, RawDocument> {
fn from(rd: RawDocumentBuf) -> Self {
Cow::Owned(rd)
}
}
impl<'a> From<&'a RawDocumentBuf> for Cow<'a, RawDocument> {
fn from(rd: &'a RawDocumentBuf) -> Self {
Cow::Borrowed(rd.as_ref())
}
}
impl TryFrom<RawDocumentBuf> for Document {
type Error = Error;
fn try_from(raw: RawDocumentBuf) -> Result<Document> {
Document::try_from(raw.as_ref())
}
}
impl<'a> IntoIterator for &'a RawDocumentBuf {
type IntoIter = Iter<'a>;
type Item = Result<(&'a str, RawBson<'a>)>;
fn into_iter(self) -> Iter<'a> {
Iter::new(self)
}
}
impl AsRef<RawDocument> for RawDocumentBuf {
fn as_ref(&self) -> &RawDocument {
RawDocument::new_unchecked(&self.data)
}
}
impl Deref for RawDocumentBuf {
type Target = RawDocument;
fn deref(&self) -> &Self::Target {
RawDocument::new_unchecked(&self.data)
}
}
impl Borrow<RawDocument> for RawDocumentBuf {
fn borrow(&self) -> &RawDocument {
&*self
}
}