use std::borrow::Cow;
use crate::{Object, Union, edge::Edge, error::Error};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize)]
pub struct ObjectRecord {
pub id: Uuid,
pub type_name: Cow<'static, str>,
pub owner: Uuid,
pub data: Vec<u8>,
pub index_meta: serde_json::Value,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl ObjectRecord {
pub fn to_object<T: Object>(self) -> Result<T, Error> {
let mut val = rmp_serde::from_slice::<T>(&self.data)
.map_err(|e| Error::Deserialize(e.to_string()))?;
let meta = val.meta_mut();
meta.id = self.id;
meta.owner = self.owner;
meta.created_at = self.created_at;
meta.updated_at = self.updated_at;
Ok(val)
}
pub fn from_object<'a, T: Object>(obj: &'a T) -> Self {
let meta = obj.meta();
Self {
id: meta.id,
type_name: Cow::Borrowed(obj.type_name()),
owner: meta.owner,
index_meta: serde_json::to_value(obj.index_meta())
.expect("Failed to serialize index_meta"),
data: obj.__serialize_internal(),
created_at: meta.created_at,
updated_at: meta.updated_at,
}
}
}
impl<A: Object, B: Object> Into<Union<A, B>> for ObjectRecord {
fn into(self) -> Union<A, B> {
match self.type_name.as_ref() {
t if t == A::TYPE => ObjectRecord::to_object::<A>(self)
.map(Union::First)
.unwrap_or_else(|err| {
panic!("Error: {:?}", err);
}),
t if t == B::TYPE => ObjectRecord::to_object::<B>(self)
.map(Union::Second)
.unwrap_or_else(|err| {
panic!("Error: {:?}", err);
}),
_ => panic!("Invalid type name"),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct EdgeRecord {
pub type_name: Cow<'static, str>,
pub from: Uuid,
pub to: Uuid,
pub data: Vec<u8>,
pub index_meta: serde_json::Value,
}
impl EdgeRecord {
pub fn to_edge<E: Edge>(self) -> Result<E, Error> {
let mut val = rmp_serde::from_slice::<E>(&self.data)
.map_err(|e| Error::Deserialize(e.to_string()))?;
let meta = val.meta_mut();
meta.to = self.to;
meta.from = self.from;
Ok(val)
}
pub fn from_edge<'a, E: Edge>(edge: &'a E) -> Self {
let meta = edge.meta();
Self {
to: meta.to,
from: meta.from,
type_name: Cow::Borrowed(edge.type_name()),
data: rmp_serde::to_vec_named(edge).expect("Failed to msgpack serialize edge"),
index_meta: serde_json::to_value(edge.index_meta())
.expect("Failed to serialize index meta"),
}
}
}