amethystate 0.9.1

Type-safe reactive persistence for Rust GUI apps
Documentation
use std::collections::HashMap;

pub trait AmeType {
    const TYPE_HASH: u32;
    const TYPE_NAME: &'static str;
}

pub const fn fnv1a(s: &[u8]) -> u32 {
    let mut hash: u32 = 0x811c9dc5;
    let mut i = 0;
    while i < s.len() {
        hash ^= s[i] as u32;
        hash = hash.wrapping_mul(0x01000193);
        i += 1;
    }
    hash
}

pub const fn schema_hash(fields: &[super::fields::FieldDescriptor]) -> u32 {
    let mut h: u32 = 0x811c9dc5;
    let mut i = 0;
    while i < fields.len() {
        let fh = fnv1a(fields[i].name.as_bytes()) ^ (fields[i].type_hash as u32);
        h ^= fh;
        h = h.wrapping_mul(0x01000193);
        i += 1;
    }
    h
}

macro_rules! impl_ame_type_primitive {
    ($($t:ty),+) => {
        $(impl AmeType for $t {
            const TYPE_HASH: u32 = fnv1a(stringify!($t).as_bytes());
            const TYPE_NAME: &'static str = stringify!($t);
        })+
    }
}

impl_ame_type_primitive!(
    u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64, usize, isize, bool, String
);

impl<T: AmeType> AmeType for Vec<T> {
    const TYPE_HASH: u32 = fnv1a(b"Vec") ^ T::TYPE_HASH;
    const TYPE_NAME: &'static str = "Vec";
}

impl<T: AmeType> AmeType for Option<T> {
    const TYPE_HASH: u32 = fnv1a(b"Option") ^ T::TYPE_HASH;
    const TYPE_NAME: &'static str = "Option";
}

impl<K: AmeType, V: AmeType> AmeType for HashMap<K, V> {
    const TYPE_HASH: u32 = fnv1a(b"HashMap") ^ K::TYPE_HASH ^ V::TYPE_HASH;
    const TYPE_NAME: &'static str = "HashMap";
}