use rkyv::{
deserialize,
with::{AsBox, MapNiche},
};
use std::{
borrow::Borrow,
hash::{Hash, Hasher},
};
use crate::{error::Error, intern::serialize_interned, schema::Etymology, serializable};
use super::{EntryRef, MediaURL};
#[macro_export]
macro_rules! entryset {
($($value:expr,)+) => { entryset!($($value),+) };
($($value:expr),*) => {
{
const CAP: usize = <[()]>::len(&[$({ stringify!($value); }),*]);
let mut set = $crate::schema::EntrySet::with_capacity(CAP);
$(
set.insert($value);
)*
set
}
};
}
serializable! {
#[derive(Default)]
#[serde(rename = "entry")]
pub struct Entry {
#[serde(rename = "@term")]
pub term: String,
#[serde(rename = "@see")]
#[rkyv(with = MapNiche<AsBox>)]
#[serde(skip_serializing_if = "Option::is_none")]
pub see_also: Option<EntryRef>,
#[serde(default, rename = "ety")]
pub etymologies: Vec<Etymology>,
#[serde(default, rename = "media")]
pub media: Vec<MediaURL>,
#[serde(rename = "@rank")]
#[rkyv(with = MapNiche<AsBox>)]
#[serde(skip_serializing_if = "Option::is_none")]
pub rank: Option<u32>,
}
}
impl Hash for Entry {
fn hash<H: Hasher>(&self, state: &mut H) {
self.term.hash(state);
}
}
impl AsRef<Entry> for Entry {
fn as_ref(&self) -> &Entry {
self
}
}
impl Borrow<str> for Entry {
fn borrow(&self) -> &str {
self.term.as_str()
}
}
impl Hash for ArchivedEntry {
fn hash<H: Hasher>(&self, state: &mut H) {
self.term.hash(state);
}
}
impl Borrow<str> for ArchivedEntry {
fn borrow(&self) -> &str {
self.term.as_str()
}
}
impl Entry {
pub fn serialize(&self) -> crate::Result<Vec<u8>> {
let bytes = serialize_interned::<_, rkyv::rancor::Error>(self)?;
Ok(bytes.to_vec())
}
}
impl ArchivedEntry {
pub fn deserialize(&self) -> crate::Result<Entry> {
let entry: Entry = deserialize::<Entry, rkyv::rancor::Error>(self)
.map_err(|e| Error::Deserialize(e.to_string()))?;
Ok(entry)
}
}