korrosync 0.4.0

A KOReader Sync Server
Documentation
use rkyv::{
    Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize,
    api::high::{HighDeserializer, HighSerializer, access},
    deserialize,
    rancor::Error,
    ser::allocator::ArenaHandle,
    util::AlignedVec,
};

use redb::{Key, TypeName, Value};
use std::{any::type_name, cmp::Ordering};

#[derive(Debug)]
pub(crate) struct Rkyv<T>(T);

impl<T> Value for Rkyv<T>
where
    T: std::fmt::Debug + Default + Archive,
    T::Archived: RkyvDeserialize<T, HighDeserializer<Error>>
        + rkyv::Portable
        + for<'a> rkyv::bytecheck::CheckBytes<rkyv::api::high::HighValidator<'a, Error>>,
    for<'a> T: RkyvSerialize<HighSerializer<AlignedVec, ArenaHandle<'a>, Error>>,
{
    type SelfType<'a>
        = T
    where
        Self: 'a;

    type AsBytes<'a>
        = AlignedVec
    where
        Self: 'a;

    fn fixed_width() -> Option<usize> {
        None
    }

    fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
    where
        Self: 'a,
    {
        if data.is_empty() {
            return T::default();
        }

        match access::<T::Archived, Error>(data) {
            Ok(archived) => deserialize::<T, Error>(archived).unwrap_or_else(|e| {
                tracing::warn!("Failed to deserialize data: {}, using default value", e);
                T::default()
            }),
            Err(e) => {
                tracing::warn!(
                    "Bytecheck validation failed: {}. Data may be corrupted, using default value",
                    e
                );
                T::default()
            }
        }
    }

    fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
    where
        Self: 'a,
        Self: 'b,
    {
        rkyv::to_bytes::<Error>(value).unwrap_or_else(|e| {
            tracing::warn!(
                "Failed to serialize value of type {}: {}. Returning empty AlignedVec",
                type_name::<T>(),
                e
            );
            AlignedVec::new()
        })
    }

    fn type_name() -> TypeName {
        TypeName::new(&format!("Rkyv<{}>", type_name::<T>()))
    }
}

impl<T> Key for Rkyv<T>
where
    T: std::fmt::Debug + Default + Archive + Ord,
    T::Archived: RkyvDeserialize<T, HighDeserializer<Error>>
        + rkyv::Portable
        + for<'a> rkyv::bytecheck::CheckBytes<rkyv::api::high::HighValidator<'a, Error>>,
    for<'a> T: RkyvSerialize<HighSerializer<AlignedVec, ArenaHandle<'a>, Error>>,
{
    fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
        Self::from_bytes(data1).cmp(&Self::from_bytes(data2))
    }
}