katana_markdown_model/source/
impls.rs1use super::types::{RawSnippet, TextFingerprint};
2use sha2::{Digest, Sha256};
3
4impl RawSnippet {
5 pub fn new(text: impl Into<String>) -> Self {
6 Self { text: text.into() }
7 }
8
9 pub fn fingerprint(&self) -> TextFingerprint {
10 TextFingerprint::for_text(&self.text)
11 }
12}
13
14impl TextFingerprint {
15 pub fn for_text(text: &str) -> Self {
16 let digest = Sha256::digest(text.as_bytes());
17 Self {
18 algorithm: "sha256".to_string(),
19 value: to_hex(&digest),
20 }
21 }
22}
23
24fn to_hex(bytes: &[u8]) -> String {
25 const HIGH_NIBBLE_SHIFT: u8 = 4;
26 const LOW_NIBBLE_MASK: u8 = 0x0f;
27 const HEX_CHARS_PER_BYTE: usize = 2;
28 const HEX: &[u8; 16] = b"0123456789abcdef";
29 let mut output = String::with_capacity(bytes.len() * HEX_CHARS_PER_BYTE);
30 for byte in bytes {
31 output.push(HEX[(byte >> HIGH_NIBBLE_SHIFT) as usize] as char);
32 output.push(HEX[(byte & LOW_NIBBLE_MASK) as usize] as char);
33 }
34 output
35}