pub mod corrupt;
pub mod ctx;
pub mod field;
pub mod gen;
pub mod locale;
pub mod pipeline;
pub mod rng;
pub mod script;
pub mod temporal;
pub mod tz;
pub mod validate;
pub const DEFAULT_TZ_OFFSET: i32 = 0;
pub const DOMAIN_IDENTITY: &str = "__identity__";
pub const DOMAIN_CORRUPT: &str = "__corrupt__";
pub const DOMAIN_SCRIPT: &str = "__script__";
pub const DOMAIN_LOCALE: &str = "__locale__";
pub const DOMAIN_TPL: &str = "__tpl__";
pub fn hash_seed(s: &str) -> u64 {
fnv1a(s.as_bytes())
}
fn fnv1a(bytes: &[u8]) -> u64 {
let mut h: u64 = 0xcbf2_9ce4_8422_2325;
for &b in bytes {
h ^= b as u64;
h = h.wrapping_mul(0x0100_0000_01b3);
}
h
}
pub fn fingerprint() -> String {
use field::REGISTRY;
const CANONICAL_SEED: &str = "__determinism__";
let master = hash_seed(CANONICAL_SEED);
let locales: Vec<&locale::Locale> = locale::get("en").into_iter().collect();
let since = temporal::parse("1900").unwrap_or(temporal::DEFAULT_SINCE);
let until = temporal::parse("2038").unwrap_or(0);
let mut buf = String::new();
let mut val_buf = String::new();
for f in REGISTRY {
let mut ctx = ctx::GenContext {
rng: rng::Rng::derive(master, 0, f.id),
locales: &locales,
modifier: "",
identity: None,
tz_offset_minutes: DEFAULT_TZ_OFFSET,
since,
until,
range: None,
ordering: crate::field::Ordering::None,
numeric: None,
};
val_buf.clear();
f.generate(&mut ctx, &mut val_buf);
buf.push_str(&val_buf);
buf.push('\0');
}
let h = fnv1a(buf.as_bytes());
format!("sf0-{h:016x}")
}