use std::hash::{Hash, Hasher};
use serde::de::DeserializeOwned;
use crate::ExtId;
use crate::sdk::describe::{DescribeDoc, Domain};
use crate::sdk::record::Record;
use crate::strategy::Strategy;
pub trait Plugin: Sized {
type Input: Record;
type Row: Clone + 'static;
type Config: DeserializeOwned + Default;
fn domain() -> Domain;
fn new(config: Self::Config) -> Self;
fn project(&self, input: &Self::Input) -> Self::Row;
fn primary(row: &Self::Row) -> i64;
fn strategy(&self) -> Box<dyn Strategy<Self::Row>>;
fn describe() -> DescribeDoc {
let d = Self::domain();
DescribeDoc::new(&d.id, &d.version).input(Self::Input::fields())
}
}
pub struct StableHasher(u64);
impl Default for StableHasher {
fn default() -> Self {
StableHasher(0xcbf29ce484222325)
}
}
impl Hasher for StableHasher {
fn finish(&self) -> u64 {
self.0
}
fn write(&mut self, bytes: &[u8]) {
for &b in bytes {
self.0 ^= b as u64;
self.0 = self.0.wrapping_mul(0x100000001b3);
}
}
}
pub fn hash_key<K: Hash>(key: &K) -> ExtId {
let mut h = StableHasher::default();
key.hash(&mut h);
h.finish()
}