typr_core/components/context/
fingerprint.rs1#![allow(dead_code, unused_variables, unused_imports)]
2use crate::components::context::Context;
18use std::fmt::Write as _;
19use std::hash::Hasher;
20
21struct HashWriter<'a, H: Hasher>(&'a mut H);
24
25impl<H: Hasher> std::fmt::Write for HashWriter<'_, H> {
26 fn write_str(&mut self, s: &str) -> std::fmt::Result {
27 self.0.write(s.as_bytes());
28 Ok(())
29 }
30}
31
32impl Context {
33 pub fn fingerprint(&self) -> u64 {
36 let mut hasher = std::collections::hash_map::DefaultHasher::new();
37 let mut w = HashWriter(&mut hasher);
38
39 for pair in self.typing_context.variables.iter() {
41 let _ = write!(w, "v{:?}", pair);
42 }
43 for pair in self.typing_context.aliases.iter() {
44 let _ = write!(w, "a{:?}", pair);
45 }
46 for pair in self.typing_context.std.iter() {
47 let _ = write!(w, "s{:?}", pair);
48 }
49 let mut counter: Vec<String> = self
52 .typing_context
53 .alias_counter
54 .clone()
55 .into_iter()
56 .map(|(category, count)| format!("{:?}={}", category, count))
57 .collect();
58 counter.sort();
59 let _ = write!(w, "c{:?}", counter);
60
61 let _ = write!(w, "g{}", self.subtypes.structure_debug());
63
64 let _ = write!(w, "tc{:?}", self.type_constructors);
66 let _ = write!(w, "ra{:?}", self.record_aliases);
67 let _ = write!(w, "em{:?}", self.embedded_methods);
68 let _ = write!(w, "ef{:?}", self.extern_fns);
69 let _ = write!(w, "if{:?}", self.import_from_fns);
70 let _ = write!(w, "sf{:?}", self.signature_fns);
71 let _ = write!(w, "vf{:?}", self.vectorizable_fns);
72
73 let mut constraints: Vec<String> = self
75 .interface_constraints
76 .iter()
77 .map(|(name, typ)| format!("{}={:?}", name, typ))
78 .collect();
79 constraints.sort();
80 let _ = write!(w, "ic{:?}", constraints);
81
82 let mut processed: Vec<String> = self
83 .processed_modules
84 .iter()
85 .map(|(name, typ)| format!("{}={:?}", name, typ))
86 .collect();
87 processed.sort();
88 let _ = write!(w, "pm{:?}", processed);
89
90 let _ = write!(w, "rc{}", self.rigid_counter);
91 let _ = write!(w, "cf{:?}", self.config);
94
95 hasher.finish()
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 use crate::components::language::var::Var;
103 use crate::utils::builder;
104
105 #[test]
106 fn fingerprint_is_deterministic_for_identical_contexts() {
107 let a = Context::default();
108 let b = Context::default();
109 assert_eq!(a.fingerprint(), b.fingerprint());
110 }
111
112 #[test]
113 fn fingerprint_changes_when_a_binding_is_added() {
114 let base = Context::default();
115 let with_var = base
116 .clone()
117 .push_var_type(Var::from_name("x"), builder::integer_type_default(), &base);
118 assert_ne!(base.fingerprint(), with_var.fingerprint());
119 }
120
121 #[test]
122 fn fingerprint_survives_clone() {
123 let base = Context::default();
124 let with_var = base
125 .clone()
126 .push_var_type(Var::from_name("x"), builder::integer_type_default(), &base);
127 assert_eq!(with_var.fingerprint(), with_var.clone().fingerprint());
128 }
129}