reductionml_core/
interactions.rs1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::{hash::hash_bytes, sparse_namespaced_features::Namespace};
5
6#[derive(Serialize, Deserialize, Clone, JsonSchema, Debug)]
7pub enum NamespaceDef {
8 Name(String),
9 Default,
10}
11
12pub type Interaction = Vec<NamespaceDef>;
13pub type HashedInteraction = Vec<Namespace>;
14
15pub fn hash_interaction(interaction: &Interaction, hash_seed: u32) -> HashedInteraction {
16 if interaction.is_empty() || interaction.len() > 3 {
17 panic!("Interaction must be between 1 and 3 namespaces")
18 }
19 interaction
20 .iter()
21 .map(|ns| match ns {
22 NamespaceDef::Name(name) => {
23 let namespace_hash = hash_bytes(name.as_bytes(), hash_seed);
24 Namespace::Named(namespace_hash.into())
25 }
26 NamespaceDef::Default => Namespace::Default,
27 })
28 .collect()
29}
30
31type InteractionPair = (Namespace, Namespace);
32type InteractionTriple = (Namespace, Namespace, Namespace);
33
34pub fn compile_interactions(
35 interactions: &[Interaction],
36 hash_seed: u32,
37) -> (Vec<InteractionPair>, Vec<InteractionTriple>) {
38 let pairs: Vec<(Namespace, Namespace)> = interactions
39 .iter()
40 .filter(|interaction| interaction.len() == 2)
41 .map(|interaction| {
42 let hashed_interaction = hash_interaction(interaction, hash_seed);
43 (hashed_interaction[0], hashed_interaction[1])
44 })
45 .collect();
46
47 let triples: Vec<(Namespace, Namespace, Namespace)> = interactions
48 .iter()
49 .filter(|interaction| interaction.len() == 3)
50 .map(|interaction| {
51 let hashed_interaction = hash_interaction(interaction, hash_seed);
52 (
53 hashed_interaction[0],
54 hashed_interaction[1],
55 hashed_interaction[2],
56 )
57 })
58 .collect();
59
60 if pairs.len() + triples.len() != interactions.len() {
61 panic!("Invalid interaction. Only pairs and triples are supported")
62 }
63
64 (pairs, triples)
65}