known_values/
known_values_registry.rs

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