use datasize::DataSize;
use minicbor::{Decode, Encode};
use sealed::sealed;
use serde::ser::{SerializeStruct, Serializer};
use serde::{Deserialize, Serialize};
use std::fmt;
use crate::annotationdataset::{AnnotationDataSet, AnnotationDataSetHandle};
use crate::error::StamError;
use crate::store::*;
use crate::types::*;
#[derive(Deserialize, Debug, Clone, DataSize, Encode, Decode)]
pub struct DataKey {
#[serde(skip)]
#[n(0)] intid: Option<DataKeyHandle>,
#[serde(rename = "@id")]
#[n(1)]
id: String,
}
impl Serialize for DataKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("DataKey", 2)?;
state.serialize_field("@type", "DataKey")?;
state.serialize_field("@id", &self.id)?;
state.end()
}
}
impl DataKey {
pub fn to_json_string(&self) -> Result<String, StamError> {
serde_json::to_string_pretty(self)
.map_err(|e| StamError::SerializationError(format!("Writing key to string: {}", e)))
}
pub fn to_json_value(&self) -> Result<serde_json::Value, StamError> {
serde_json::to_value(self)
.map_err(|e| StamError::SerializationError(format!("Producing Json Value: {}", e)))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, DataSize, Encode, Decode)]
#[cbor(transparent)]
pub struct DataKeyHandle(#[n(0)] u16);
#[sealed]
impl Handle for DataKeyHandle {
fn new(intid: usize) -> Self {
Self(intid as u16)
}
fn as_usize(&self) -> usize {
self.0 as usize
}
}
impl<'a> Request<DataKey> for DataKeyHandle {
fn to_handle<'store, S>(&self, _store: &'store S) -> Option<DataKeyHandle>
where
S: StoreFor<DataKey>,
{
Some(*self)
}
}
impl<'a> Request<DataKey> for Option<DataKeyHandle> {
fn to_handle<'store, S>(&self, _store: &'store S) -> Option<DataKeyHandle>
where
S: StoreFor<DataKey>,
{
*self
}
fn any(&self) -> bool {
self.is_none()
}
}
impl<'a> From<&DataKeyHandle> for BuildItem<'a, DataKey> {
fn from(handle: &DataKeyHandle) -> Self {
BuildItem::Handle(*handle)
}
}
impl<'a> From<Option<&DataKeyHandle>> for BuildItem<'a, DataKey> {
fn from(handle: Option<&DataKeyHandle>) -> Self {
if let Some(handle) = handle {
BuildItem::Handle(*handle)
} else {
BuildItem::None
}
}
}
impl<'a> From<DataKeyHandle> for BuildItem<'a, DataKey> {
fn from(handle: DataKeyHandle) -> Self {
BuildItem::Handle(handle)
}
}
impl<'a> From<Option<DataKeyHandle>> for BuildItem<'a, DataKey> {
fn from(handle: Option<DataKeyHandle>) -> Self {
if let Some(handle) = handle {
BuildItem::Handle(handle)
} else {
BuildItem::None
}
}
}
#[sealed]
impl TypeInfo for DataKey {
fn typeinfo() -> Type {
Type::DataKey
}
}
#[sealed]
impl Storable for DataKey {
type HandleType = DataKeyHandle;
type StoreHandleType = AnnotationDataSetHandle;
type FullHandleType = (AnnotationDataSetHandle, DataKeyHandle);
type StoreType = AnnotationDataSet;
fn id(&self) -> Option<&str> {
Some(self.id.as_str())
}
fn handle(&self) -> Option<DataKeyHandle> {
self.intid
}
fn with_handle(mut self, intid: DataKeyHandle) -> Self {
self.intid = Some(intid);
self
}
fn with_id(mut self, id: impl Into<String>) -> Self {
self.id = id.into();
self
}
fn carries_id() -> bool {
true
}
fn fullhandle(
storehandle: Self::StoreHandleType,
handle: Self::HandleType,
) -> Self::FullHandleType {
(storehandle, handle)
}
fn merge(&mut self, other: Self) -> Result<(), StamError> {
let intid = self.intid;
*self = other;
self.intid = intid; Ok(())
}
fn unbind(mut self) -> Self {
self.intid = None;
self
}
}
impl PartialEq<DataKey> for DataKey {
fn eq(&self, other: &DataKey) -> bool {
self.id == other.id
}
}
impl fmt::Display for DataKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl PartialEq<str> for DataKey {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl PartialEq<DataKey> for str {
fn eq(&self, other: &DataKey) -> bool {
other.as_str() == self
}
}
impl DataKey {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
intid: None,
}
}
pub fn as_str(&self) -> &str {
self.id.as_str()
}
pub fn to_json(&self) -> Result<String, StamError> {
serde_json::to_string_pretty(&self).map_err(|e| {
StamError::SerializationError(format!("Serializing datakey to string: {}", e))
})
}
pub fn to_json_compact(&self) -> Result<String, StamError> {
serde_json::to_string(&self).map_err(|e| {
StamError::SerializationError(format!("Serializing datakey to string: {}", e))
})
}
}