darklua_core/rules/
runtime_identifier.rs1use blake3;
2use hex;
3use std::collections::HashMap;
4use strfmt::strfmt;
5
6pub struct RuntimeIdentifierBuilder {
7 format: String,
8 hash: String,
9 keywords: Option<Vec<String>>,
10}
11
12impl RuntimeIdentifierBuilder {
13 pub fn new(
14 format: impl Into<String>,
15 identifier: &[u8],
16 keywords: Option<Vec<String>>,
17 ) -> Result<Self, String> {
18 let format: String = format.into();
19 if !format.as_str().contains("{name}") {
20 return Err("`name` field is required for runtime identifier".to_string());
21 }
22 let hash = blake3::hash(identifier);
23 Ok(Self {
24 format,
25 hash: hex::encode(&hash.as_bytes()[..8]),
26 keywords,
27 })
28 }
29
30 pub fn build(&self, name: &str) -> Result<String, String> {
31 let mut vars = HashMap::new();
32 vars.insert("name".to_owned(), name);
33 vars.insert("hash".to_owned(), self.hash.as_str());
34
35 let name = strfmt(&self.format, &vars).map_err(|err| err.to_string())?;
36
37 if let Some(keywords) = &self.keywords {
38 if keywords.contains(&name) {
39 Err(format!("Runtime variable `{name}` cannot be set because it contains a reserved keyword."))?;
40 }
41 }
42
43 Ok(name)
44 }
45}