Skip to main content

somatize_core/
key.rs

1//! What names what a node produces, before it produces it.
2//!
3//! A key is a Merkle hash **over the recipe** and not over the data: the
4//! identity of the node, what it was built with, the digest of the state it is
5//! settled at, and the keys of its predecessors. Only a root hashes content, so
6//! the key is known before anything runs and changing the classifier does not
7//! touch the key of the embeddings underneath it.
8//!
9//! The core computes none of them: hashing needs an algorithm and the core has
10//! no dependencies, so a `Key` arrives from the [`Keeper`](crate::Keeper) and
11//! this is only the shape it arrives in.
12
13use std::fmt;
14
15/// What a node's output is called, wherever it is kept. Text and not bytes
16/// because it is a name: it ends up in an index, a log line and an error.
17#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
18#[cfg_attr(
19    feature = "serde",
20    derive(serde::Serialize, serde::Deserialize),
21    serde(transparent)
22)]
23pub struct Key(String);
24
25impl Key {
26    /// A key somebody else computed. Only a [`Keeper`](crate::Keeper) should be
27    /// calling this: two keys made by different recipes have to be different,
28    /// and nothing here can check that.
29    pub fn new(text: impl Into<String>) -> Self {
30        Self(text.into())
31    }
32
33    /// As text.
34    pub fn as_str(&self) -> &str {
35        &self.0
36    }
37}
38
39impl fmt::Display for Key {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        f.write_str(&self.0)
42    }
43}
44
45/// What a node's output is called: one name, or one per item.
46///
47/// The second is what a [`.mapped()`](crate::Memory::map) node produces: with
48/// one name per node, adding a document to a list of a thousand misses all
49/// thousand; with one per item, the thousand hit and the new one runs.
50#[derive(Debug, Clone, PartialEq, Eq)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52pub enum Keys {
53    /// The output is one thing and has one name.
54    One(Key),
55    /// The output is a list, and each item is named on its own — in order, and
56    /// as long as the list.
57    PerItem(Vec<Key>),
58}
59
60impl Keys {
61    /// The one name, if there is one. `None` for a list of them: what a single
62    /// name over many is made of is
63    /// [`Keeper::combine`](crate::Keeper::combine)'s to decide.
64    pub fn one(&self) -> Option<&Key> {
65        match self {
66            Self::One(key) => Some(key),
67            Self::PerItem(_) => None,
68        }
69    }
70
71    /// Every name in it, in order: one, or as many as there are items.
72    pub fn each(&self) -> &[Key] {
73        match self {
74            Self::One(key) => std::slice::from_ref(key),
75            Self::PerItem(keys) => keys,
76        }
77    }
78}
79
80impl fmt::Display for Keys {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        match self {
83            Self::One(key) => key.fmt(f),
84            Self::PerItem(keys) => write!(f, "{} items", keys.len()),
85        }
86    }
87}