Skip to main content

known_values/
known_values_registry.rs

1use std::sync::{Mutex, Once};
2
3use paste::paste;
4
5use super::KnownValuesStore;
6
7/// A macro that declares a known value at compile time.
8///
9/// This macro creates two constants:
10/// - A raw u64 value constant with the suffix `_RAW`
11/// - A KnownValue constant with the given name and value
12///
13/// This is used internally to define all the standard Known Values in the
14/// registry.
15///
16/// # Examples
17///
18/// ```
19/// use known_values::*;
20/// use paste::paste;
21///
22/// // Define a custom known value
23/// const_known_value!(1000, MY_CUSTOM_VALUE, "myCustomValue");
24///
25/// // Now MY_CUSTOM_VALUE is a constant KnownValue
26/// assert_eq!(MY_CUSTOM_VALUE.value(), 1000);
27/// assert_eq!(MY_CUSTOM_VALUE.name(), "myCustomValue");
28///
29/// paste! {
30///     // MY_CUSTOM_VALUE_RAW is the raw u64 value
31///     assert_eq!([<MY_CUSTOM_VALUE _RAW>], 1000);
32/// }
33/// ```
34#[macro_export]
35macro_rules! const_known_value {
36    ($value:expr, $const_name:ident, $name:expr) => {
37        paste! {
38            pub const [<$const_name _RAW>]: u64 = $value;
39        }
40        pub const $const_name: $crate::KnownValue =
41            $crate::KnownValue::new_with_static_name($value, $name);
42    };
43}
44
45// For definitions see: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-002-known-value.md#appendix-a-registry
46
47//
48// General
49//
50
51const_known_value!(0, UNIT, "");
52const_known_value!(1, IS_A, "isA");
53const_known_value!(2, ID, "id");
54const_known_value!(3, SIGNED, "signed");
55const_known_value!(4, NOTE, "note");
56const_known_value!(5, HAS_RECIPIENT, "hasRecipient");
57const_known_value!(6, SSKR_SHARE, "sskrShare");
58const_known_value!(7, CONTROLLER, "controller");
59const_known_value!(8, KEY, "key");
60const_known_value!(9, DEREFERENCE_VIA, "dereferenceVia");
61const_known_value!(10, ENTITY, "entity");
62const_known_value!(11, NAME, "name");
63const_known_value!(12, LANGUAGE, "language");
64const_known_value!(13, ISSUER, "issuer");
65const_known_value!(14, HOLDER, "holder");
66const_known_value!(15, SALT, "salt");
67const_known_value!(16, DATE, "date");
68const_known_value!(17, UNKNOWN_VALUE, "Unknown");
69const_known_value!(18, VERSION_VALUE, "version");
70const_known_value!(19, HAS_SECRET, "hasSecret");
71const_known_value!(20, DIFF_EDITS, "edits");
72const_known_value!(21, VALID_FROM, "validFrom");
73const_known_value!(22, VALID_UNTIL, "validUntil");
74const_known_value!(23, POSITION, "position");
75const_known_value!(24, NICKNAME, "nickname");
76const_known_value!(25, VALUE, "value");
77const_known_value!(26, ATTESTATION, "attestation");
78const_known_value!(27, VERIFIABLE_AT, "verifiableAt");
79// 26-49 *unassigned*
80
81//
82// Attachments
83//
84
85const_known_value!(50, ATTACHMENT, "attachment");
86const_known_value!(51, VENDOR, "vendor");
87const_known_value!(52, CONFORMS_TO, "conformsTo");
88// 53-59 *unassigned*
89
90//
91// XID Documents
92//
93
94const_known_value!(60, ALLOW, "allow");
95const_known_value!(61, DENY, "deny");
96const_known_value!(62, ENDPOINT, "endpoint");
97const_known_value!(63, DELEGATE, "delegate");
98const_known_value!(64, PROVENANCE, "provenance");
99const_known_value!(65, PRIVATE_KEY, "privateKey");
100const_known_value!(66, SERVICE, "service");
101const_known_value!(67, CAPABILITY, "capability");
102const_known_value!(68, PROVENANCE_GENERATOR, "provenanceGenerator");
103// 68-69 *unassigned*
104
105//
106// XID Privileges
107//
108
109const_known_value!(70, PRIVILEGE_ALL, "All");
110const_known_value!(71, PRIVILEGE_AUTH, "Authorize");
111const_known_value!(72, PRIVILEGE_SIGN, "Sign");
112const_known_value!(73, PRIVILEGE_ENCRYPT, "Encrypt");
113const_known_value!(74, PRIVILEGE_ELIDE, "Elide");
114const_known_value!(75, PRIVILEGE_ISSUE, "Issue");
115const_known_value!(76, PRIVILEGE_ACCESS, "Access");
116// 77-79 *unassigned*
117const_known_value!(80, PRIVILEGE_DELEGATE, "Delegate");
118const_known_value!(81, PRIVILEGE_VERIFY, "Verify");
119const_known_value!(82, PRIVILEGE_UPDATE, "Update");
120const_known_value!(83, PRIVILEGE_TRANSFER, "Transfer");
121const_known_value!(84, PRIVILEGE_ELECT, "Elect");
122const_known_value!(85, PRIVILEGE_BURN, "Burn");
123const_known_value!(86, PRIVILEGE_REVOKE, "Revoke");
124// 87-99 *unassigned*
125
126//
127// Expression and Function Calls
128//
129
130const_known_value!(100, BODY, "body");
131const_known_value!(101, RESULT, "result");
132const_known_value!(102, ERROR, "error");
133const_known_value!(103, OK_VALUE, "OK");
134const_known_value!(104, PROCESSING_VALUE, "Processing");
135const_known_value!(105, SENDER, "sender");
136const_known_value!(106, SENDER_CONTINUATION, "senderContinuation");
137const_known_value!(107, RECIPIENT_CONTINUATION, "recipientContinuation");
138const_known_value!(108, CONTENT, "content");
139// 109-199 *unassigned*
140
141//
142// Cryptography
143//
144
145const_known_value!(200, SEED_TYPE, "Seed");
146const_known_value!(201, PRIVATE_KEY_TYPE, "PrivateKey");
147const_known_value!(202, PUBLIC_KEY_TYPE, "PublicKey");
148const_known_value!(203, MASTER_KEY_TYPE, "MasterKey");
149// 204-299 *unassigned*
150
151//
152// Cryptocurrency Assets
153//
154
155const_known_value!(300, ASSET, "asset");
156const_known_value!(301, BITCOIN_VALUE, "Bitcoin");
157const_known_value!(302, ETHEREUM_VALUE, "Ethereum");
158const_known_value!(303, TEZOS_VALUE, "Tezos");
159// 304-399 *unassigned*
160
161//
162// Cryptocurrency Networks
163//
164
165const_known_value!(400, NETWORK, "network");
166const_known_value!(401, MAIN_NET_VALUE, "MainNet");
167const_known_value!(402, TEST_NET_VALUE, "TestNet");
168// 403-499 *unassigned*
169
170//
171// Bitcoin
172//
173
174const_known_value!(500, BIP32_KEY_TYPE, "BIP32Key");
175const_known_value!(501, CHAIN_CODE, "chainCode");
176const_known_value!(502, DERIVATION_PATH_TYPE, "DerivationPath");
177const_known_value!(503, PARENT_PATH, "parentPath");
178const_known_value!(504, CHILDREN_PATH, "childrenPath");
179const_known_value!(505, PARENT_FINGERPRINT, "parentFingerprint");
180const_known_value!(506, PSBT_TYPE, "PSBT");
181const_known_value!(507, OUTPUT_DESCRIPTOR_TYPE, "OutputDescriptor");
182const_known_value!(508, OUTPUT_DESCRIPTOR, "outputDescriptor");
183// 509-599 *unassigned*
184
185//
186// Graphs
187//
188
189const_known_value!(600, GRAPH, "Graph");
190const_known_value!(601, SOURCE_TARGET_GRAPH, "SourceTargetGraph");
191const_known_value!(602, PARENT_CHILD_GRAPH, "ParentChildGraph");
192const_known_value!(603, DIGRAPH, "Digraph");
193const_known_value!(604, ACYCLIC_GRAPH, "AcyclicGraph");
194const_known_value!(605, MULTIGRAPH, "Multigraph");
195const_known_value!(606, PSEUDOGRAPH, "Pseudograph");
196const_known_value!(607, GRAPH_FRAGMENT, "GraphFragment");
197const_known_value!(608, DAG, "DAG");
198const_known_value!(609, TREE, "Tree");
199const_known_value!(610, FOREST, "Forest");
200const_known_value!(611, COMPOUND_GRAPH, "CompoundGraph");
201const_known_value!(612, HYPERGRAPH, "Hypergraph");
202const_known_value!(613, DIHYPERGRAPH, "Dihypergraph");
203// 614-699 *unassigned*
204const_known_value!(700, NODE, "node");
205const_known_value!(701, EDGE, "edge");
206const_known_value!(702, SOURCE, "source");
207const_known_value!(703, TARGET, "target");
208const_known_value!(704, PARENT, "parent");
209const_known_value!(705, CHILD, "child");
210const_known_value!(706, SELF, "Self");
211// 707-... *unassigned*
212
213/// A lazily initialized singleton that holds the global registry of known
214/// values.
215///
216/// This type provides thread-safe, lazy initialization of the global
217/// KnownValuesStore that contains all the predefined Known Values in the
218/// registry. The store is created only when first accessed, and subsequent
219/// accesses reuse the same instance.
220///
221/// This is used internally by the crate and should not typically be needed by
222/// users of the API, who should access Known Values through the constants
223/// exposed in the `known_values` module.
224///
225/// # Thread Safety
226///
227/// The implementation uses a mutex to protect the store, and initialization is
228/// performed only once across all threads using `std::sync::Once`.
229#[doc(hidden)]
230#[derive(Debug)]
231pub struct LazyKnownValues {
232    init: Once,
233    data: Mutex<Option<KnownValuesStore>>,
234}
235
236impl LazyKnownValues {
237    /// Gets the global KnownValuesStore, initializing it if necessary.
238    ///
239    /// This method guarantees that initialization occurs exactly once,
240    /// even when called from multiple threads simultaneously.
241    ///
242    /// When the `directory-loading` feature is enabled, this method will:
243    /// 1. Initialize the store with hardcoded known values
244    /// 2. Load additional values from configured directories (default:
245    ///    `~/.known-values/`)
246    /// 3. Override hardcoded values with directory-loaded values when
247    ///    codepoints match
248    pub fn get(&self) -> std::sync::MutexGuard<'_, Option<KnownValuesStore>> {
249        self.init.call_once(|| {
250            #[allow(unused_mut)]
251            let mut m = KnownValuesStore::new([
252                UNIT,
253                IS_A,
254                ID,
255                SIGNED,
256                NOTE,
257                HAS_RECIPIENT,
258                SSKR_SHARE,
259                CONTROLLER,
260                KEY,
261                DEREFERENCE_VIA,
262                ENTITY,
263                NAME,
264                LANGUAGE,
265                ISSUER,
266                HOLDER,
267                SALT,
268                DATE,
269                UNKNOWN_VALUE,
270                VERSION_VALUE,
271                HAS_SECRET,
272                DIFF_EDITS,
273                VALID_FROM,
274                VALID_UNTIL,
275                POSITION,
276                NICKNAME,
277                ATTESTATION,
278                VERIFIABLE_AT,
279                ATTACHMENT,
280                VENDOR,
281                CONFORMS_TO,
282                ALLOW,
283                DENY,
284                ENDPOINT,
285                DELEGATE,
286                PROVENANCE,
287                PRIVATE_KEY,
288                SERVICE,
289                CAPABILITY,
290                PROVENANCE_GENERATOR,
291                PRIVILEGE_ALL,
292                PRIVILEGE_AUTH,
293                PRIVILEGE_SIGN,
294                PRIVILEGE_ENCRYPT,
295                PRIVILEGE_ELIDE,
296                PRIVILEGE_ISSUE,
297                PRIVILEGE_ACCESS,
298                PRIVILEGE_DELEGATE,
299                PRIVILEGE_VERIFY,
300                PRIVILEGE_UPDATE,
301                PRIVILEGE_TRANSFER,
302                PRIVILEGE_ELECT,
303                PRIVILEGE_BURN,
304                PRIVILEGE_REVOKE,
305                BODY,
306                RESULT,
307                ERROR,
308                OK_VALUE,
309                PROCESSING_VALUE,
310                SENDER,
311                SENDER_CONTINUATION,
312                RECIPIENT_CONTINUATION,
313                CONTENT,
314                SEED_TYPE,
315                PRIVATE_KEY_TYPE,
316                PUBLIC_KEY_TYPE,
317                MASTER_KEY_TYPE,
318                ASSET,
319                BITCOIN_VALUE,
320                ETHEREUM_VALUE,
321                TEZOS_VALUE,
322                NETWORK,
323                MAIN_NET_VALUE,
324                TEST_NET_VALUE,
325                BIP32_KEY_TYPE,
326                CHAIN_CODE,
327                DERIVATION_PATH_TYPE,
328                PARENT_PATH,
329                CHILDREN_PATH,
330                PARENT_FINGERPRINT,
331                PSBT_TYPE,
332                OUTPUT_DESCRIPTOR_TYPE,
333                OUTPUT_DESCRIPTOR,
334                GRAPH,
335                SOURCE_TARGET_GRAPH,
336                PARENT_CHILD_GRAPH,
337                DIGRAPH,
338                ACYCLIC_GRAPH,
339                MULTIGRAPH,
340                PSEUDOGRAPH,
341                GRAPH_FRAGMENT,
342                DAG,
343                TREE,
344                FOREST,
345                COMPOUND_GRAPH,
346                HYPERGRAPH,
347                DIHYPERGRAPH,
348                NODE,
349                EDGE,
350                SOURCE,
351                TARGET,
352                PARENT,
353                CHILD,
354            ]);
355
356            // When directory-loading feature is enabled, load additional values
357            // from configured directories. Values from directories override
358            // hardcoded values when codepoints match.
359            #[cfg(feature = "directory-loading")]
360            {
361                let config = crate::directory_loader::get_and_lock_config();
362                let result = crate::directory_loader::load_from_config(&config);
363                for value in result.into_values() {
364                    m.insert(value);
365                }
366            }
367
368            *self.data.lock().unwrap() = Some(m);
369        });
370        self.data.lock().unwrap()
371    }
372}
373
374/// The global registry of Known Values.
375///
376/// This static instance provides access to all standard Known Values defined in
377/// the registry specification. It is lazily initialized on first access.
378///
379/// Most users should not need to interact with this directly, as the predefined
380/// Known Values are exposed as constants in the `known_values` module.
381///
382/// # Examples
383///
384/// ```
385/// use known_values::*;
386///
387/// // Access the global store
388/// let binding = KNOWN_VALUES.get();
389/// let known_values = binding.as_ref().unwrap();
390///
391/// // Look up a Known Value by name
392/// let is_a = known_values.known_value_named("isA").unwrap();
393/// assert_eq!(is_a.value(), 1);
394/// ```
395pub static KNOWN_VALUES: LazyKnownValues =
396    LazyKnownValues { init: Once::new(), data: Mutex::new(None) };
397
398#[cfg(test)]
399mod tests {
400    #[test]
401    fn test_1() {
402        assert_eq!(crate::IS_A.value(), 1);
403        assert_eq!(crate::IS_A.name(), "isA");
404        let binding = crate::KNOWN_VALUES.get();
405        let known_values = binding.as_ref().unwrap();
406        assert_eq!(known_values.known_value_named("isA").unwrap().value(), 1);
407    }
408}