mod cache;
mod memoryblobstore;
pub mod schemas;
use crate::metadata::ConstId;
use crate::value::schemas::hash::Handle;
use crate::value::schemas::hash::HashProtocol;
use crate::value::Value;
use crate::value::ValueSchema;
use std::convert::Infallible;
use std::error::Error;
use std::fmt::Debug;
use std::fmt::{self};
use std::hash::Hash;
use std::marker::PhantomData;
pub use cache::BlobCache;
pub use memoryblobstore::MemoryBlobStore;
pub use anybytes::Bytes;
#[repr(transparent)]
pub struct Blob<S: BlobSchema> {
pub bytes: Bytes,
_schema: PhantomData<S>,
}
impl<S: BlobSchema> Blob<S> {
pub fn new(bytes: Bytes) -> Self {
Self {
bytes,
_schema: PhantomData,
}
}
pub fn transmute<T: BlobSchema>(self) -> Blob<T> {
Blob {
bytes: self.bytes,
_schema: PhantomData,
}
}
pub fn as_transmute<T: BlobSchema>(&self) -> &Blob<T> {
unsafe { std::mem::transmute(self) }
}
pub fn get_handle<H>(&self) -> Value<Handle<H, S>>
where
H: HashProtocol,
Handle<H, S>: ValueSchema,
{
let digest = H::digest(&self.bytes);
Value::new(digest.into())
}
pub fn try_from_blob<T>(self) -> Result<T, <T as TryFromBlob<S>>::Error>
where
T: TryFromBlob<S>,
{
<T as TryFromBlob<S>>::try_from_blob(self)
}
}
impl<T: BlobSchema> Clone for Blob<T> {
fn clone(&self) -> Self {
Self {
bytes: self.bytes.clone(),
_schema: PhantomData,
}
}
}
impl<T: BlobSchema> PartialEq for Blob<T> {
fn eq(&self, other: &Self) -> bool {
self.bytes == other.bytes
}
}
impl<T: BlobSchema> Eq for Blob<T> {}
impl<T: BlobSchema> Hash for Blob<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.bytes.hash(state);
}
}
impl<T: BlobSchema> Debug for Blob<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Blob<{}>", std::any::type_name::<T>())
}
}
pub trait BlobSchema: ConstId + Sized + 'static {
fn blob_from<T: ToBlob<Self>>(t: T) -> Blob<Self> {
t.to_blob()
}
}
pub trait ToBlob<S: BlobSchema> {
fn to_blob(self) -> Blob<S>;
}
pub trait TryFromBlob<S: BlobSchema>: Sized {
type Error: Error + Send + Sync + 'static;
fn try_from_blob(b: Blob<S>) -> Result<Self, Self::Error>;
}
impl<S: BlobSchema> TryFromBlob<S> for Blob<S> {
type Error = Infallible;
fn try_from_blob(b: Blob<S>) -> Result<Self, Self::Error> {
Ok(b)
}
}
impl<S: BlobSchema> ToBlob<S> for Blob<S> {
fn to_blob(self) -> Blob<S> {
self
}
}