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
71 let mut constraints: Vec<String> = self
73 .interface_constraints
74 .iter()
75 .map(|(name, typ)| format!("{}={:?}", name, typ))
76 .collect();
77 constraints.sort();
78 let _ = write!(w, "ic{:?}", constraints);
79
80 let mut processed: Vec<String> = self
81 .processed_modules
82 .iter()
83 .map(|(name, typ)| format!("{}={:?}", name, typ))
84 .collect();
85 processed.sort();
86 let _ = write!(w, "pm{:?}", processed);
87
88 let _ = write!(w, "rc{}", self.rigid_counter);
89 let _ = write!(w, "cf{:?}", self.config);
92
93 hasher.finish()
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use crate::components::language::var::Var;
101 use crate::utils::builder;
102
103 #[test]
104 fn fingerprint_is_deterministic_for_identical_contexts() {
105 let a = Context::default();
106 let b = Context::default();
107 assert_eq!(a.fingerprint(), b.fingerprint());
108 }
109
110 #[test]
111 fn fingerprint_changes_when_a_binding_is_added() {
112 let base = Context::default();
113 let with_var =
114 base.clone()
115 .push_var_type(Var::from_name("x"), builder::integer_type_default(), &base);
116 assert_ne!(base.fingerprint(), with_var.fingerprint());
117 }
118
119 #[test]
120 fn fingerprint_survives_clone() {
121 let base = Context::default();
122 let with_var =
123 base.clone()
124 .push_var_type(Var::from_name("x"), builder::integer_type_default(), &base);
125 assert_eq!(with_var.fingerprint(), with_var.clone().fingerprint());
126 }
127}