#![warn(clippy::unwrap_used)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), macro_use)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[macro_use]
extern crate tracing;
#[macro_use]
extern crate metrics;
pub use armour_core;
pub use armour_derive::*;
pub use async_broadcast::RecvError;
pub use cid::{Cid, KeyScheme, KeyType};
pub use dyn_types::{Typ, get_type::GetType, value::Value};
pub use error::{DbError, DbResult};
#[cfg(feature = "fjall")]
pub use fjall::{self, Slice};
pub use indexes::index::{CompositionIndex, HashIndexExtractor};
#[cfg(feature = "fjall")]
pub use logdb::{IterTree, db::Db, read::ReadTree, tree::TypedTree};
pub use rapira;
pub use record::{Migration, Record};
#[cfg(feature = "fjall")]
pub use transactional::{db::TxDb, raw::TxRawTree, read::TxReadTree, tree::TxTree};
pub use types::{entry::Entry, fuid::Fuid, id64::Id64, record_status::RecordStatus};
pub mod cid;
pub mod dyn_types;
pub mod error;
pub mod indexes;
#[cfg(feature = "fjall")]
pub mod logdb;
#[cfg(feature = "fjall")]
mod migration;
pub mod record;
pub mod replication;
#[cfg(feature = "fjall")]
pub mod snapshot;
#[cfg(feature = "fjall")]
pub mod transactional;
pub mod types;
pub mod utils;
#[cfg(feature = "rpc")]
pub mod rpc;
pub mod migrations {
pub use crate::record::{MigrationRes, MigrationType};
}
pub type KV<K, V> = (K, V);
pub use armour_core::const_hasher;
pub use armour_core::hasher;
#[macro_export]
macro_rules! rapira_record {
($ty: ty, $id_ty: ty, $value_ty: ty, $name: literal) => {
impl $crate::Record for $ty {
type SelfId = $id_ty;
type Value = $value_ty;
const NAME: &'static str = $name;
const SIZE: Option<usize> = <Self as rapira::Rapira>::STATIC_SIZE;
fn deser(bytes: &Self::Value) -> Self {
rapira::deserialize(bytes.as_ref()).unwrap()
}
fn ser(&self) -> $value_ty {
rapira::serialize(self).into()
}
}
};
}
#[macro_export]
macro_rules! zerocopy_record {
($ty: ty, $id_ty: ty, $value_ty: ty, $name: literal) => {
impl $ty {
const INNER_SIZE: usize = std::mem::size_of::<$ty>();
}
impl $crate::Record for $ty {
type SelfId = $id_ty;
type Value = $value_ty;
const NAME: &'static str = $name;
const SIZE: Option<usize> = Some(Self::INNER_SIZE);
fn deser(bytes: &Self::Value) -> Self {
let bytes: &[u8] = bytes.as_ref();
let bytes: [u8; Self::INNER_SIZE] = bytes.try_into().unwrap();
zerocopy::transmute!(bytes)
}
fn ser(&self) -> $value_ty {
let bytes: &[u8; Self::INNER_SIZE] = zerocopy::transmute_ref!(self);
bytes.into()
}
}
};
}
#[macro_export]
macro_rules! bytemuck_slice_record {
($ty: ty, $id_ty: ty, $value_ty: ty, $name: literal) => {
impl $crate::Record for $ty {
type SelfId = $id_ty;
type Value = $value_ty;
const NAME: &'static str = $name;
fn deser(bytes: &Self::Value) -> Self {
if bytes.is_empty() {
return Default::default();
}
let vec = bytes.as_ref().to_vec();
let vec: Vec<ProfileId> = bytemuck::cast_vec(vec);
Self(vec)
}
fn ser(&self) -> $value_ty {
let bytes: &[u8] = bytemuck::cast_slice(self);
bytes.to_vec().into()
}
}
};
}
#[macro_export]
macro_rules! zerocopy_cid {
($ty: ty, [$($key_type:expr),*], $group_bits:expr, $field:ident) => {
impl $crate::Cid for $ty {
type B = [u8; size_of::<Self>()];
const TY: $crate::KeyScheme = $crate::KeyScheme::Typed(&[$($key_type),*]);
const GROUP_BITS: u32 = $group_bits;
fn encode(&self) -> Self::B {
zerocopy::transmute!(*self)
}
fn decode(bytes: &Self::B) -> armour::types::Result<Self> {
Ok(zerocopy::transmute!(*bytes))
}
fn group_id(&self) -> u32 {
self.$field.group_id()
}
}
};
}
#[cfg(test)]
mod tests {
use rapira::Rapira;
use super::*;
use crate::types::id64::Id64;
#[derive(Clone, Rapira)]
struct User {
name: String,
}
impl GetType for User {
const TYPE: Typ = Typ::Custom("unimplemented", &[]);
}
const_hasher!(test_key, "TEST");
type UserID = Id64<test_key::Hasher>;
rapira_record!(User, UserID, Vec<u8>, "users");
#[test]
fn test_rapira_record() {
let _user = User {
name: "John Doe".to_string(),
};
}
}