//! Content-addressed hashing for definitions. //! //! Hash = BLAKE3 over the canonical JSON bytes of a [`Def`] (see //! [`crate::canonical`]). The hash function takes a [`Def`] by //! reference, so there is no `hash` field to strip — the in-memory //! struct does not carry one. //! //! The single entry point at this level is [`def_hash`]. The parallel //! entry point at module granularity is //! [`crate::workspace::module_hash`]. use crate::ast::Def; use crate::canonical; /// Content hash of a single [`Def`] — the 16-hex-char (64-bit) prefix /// of its BLAKE3 hash over canonical JSON bytes. /// /// 64 bits is wide enough to be unique across realistic AILang /// codebases and short enough to read at a glance in pretty-printed /// manifests. The hash is computed over the **canonical JSON byte /// pre-image**, not over the in-memory struct, so any change to the /// canonical form (new fields, different `skip_serializing_if` /// behaviour, key reordering bug) changes every hash. The Iter 13a /// regression test below pins concrete hashes for two example /// definitions to catch that. /// /// # Examples /// /// ```ignore /// use ailang_core::{ast::*, def_hash}; /// /// let def = Def::Const(ConstDef { /// name: "answer".into(), /// ty: Type::int(), /// value: Term::Lit { lit: Literal::Int { value: 42 } }, /// doc: None, /// }); /// /// // Stable across runs: same canonical bytes -> same hash. /// assert_eq!(def_hash(&def), def_hash(&def)); /// assert_eq!(def_hash(&def).len(), 16); /// ``` pub fn def_hash(def: &Def) -> String { let bytes = canonical::to_bytes(def); let h = blake3::hash(&bytes); let hex = h.to_hex(); hex.as_str()[..16].to_string() } // `#[cfg(test)] mod tests` block relocated to // `crates/ailang-core/tests/hash_pin.rs` in iter form-a.1 Task 5. The // integration-test crate has `ailang-surface` as a dev-dependency so // the schema-stability pins can load `.ail` fixtures via // `ailang_surface::load_module`, eliminating the production-source // dependency on `.ail.json` fixture reads. #[cfg(test)] mod tests {}