use dcbor::Tag;
use paste::paste;
use std::sync::{Once, Mutex};
use dcbor::TagsStore;
#[macro_export]
macro_rules! tag_constant {
($const_name:ident, $value:expr, $name:expr) => {
paste! {
pub const [<$const_name _VALUE>]: u64 = $value;
}
pub const $const_name: Tag = Tag::new_with_static_name($value, $name);
};
}
tag_constant!(DATE, 1, "date");
tag_constant!(URI, 32, "url");
tag_constant!(UUID, 37, "uuid");
tag_constant!(LEAF, 24, "leaf");
tag_constant!(ENVELOPE, 200, "envelope");
tag_constant!(KNOWN_VALUE, 40000, "known-value");
tag_constant!(DIGEST, 40001, "digest");
tag_constant!(ENCRYPTED, 40002, "encrypted");
tag_constant!(COMPRESSED, 40003, "compressed");
tag_constant!(REQUEST, 40004, "request");
tag_constant!(RESPONSE, 40005, "response");
tag_constant!(FUNCTION, 40006, "function");
tag_constant!(PARAMETER, 40007, "parameter");
tag_constant!(PLACEHOLDER, 40008, "placeholder");
tag_constant!(REPLACEMENT, 40009, "replacement");
tag_constant!(SEED, 300, "crypto-seed"); tag_constant!(EC_KEY, 306, "crypto-eckey"); tag_constant!(SSKR_SHARE, 309, "crypto-sskr"); tag_constant!(AGREEMENT_PRIVATE_KEY, 40010, "agreement-private-key");
tag_constant!(AGREEMENT_PUBLIC_KEY, 40011, "agreement-public-key");
tag_constant!(CID, 40012, "cid");
tag_constant!(SEED_DIGEST, 40013, "seed-digest");
tag_constant!(NONCE, 40014, "nonce");
tag_constant!(PASSWORD, 40015, "password");
tag_constant!(PRIVATE_KEYBASE, 40016, "crypto-prvkeys");
tag_constant!(PUBLIC_KEYBASE, 40017, "crypto-pubkeys");
tag_constant!(SALT, 40018, "salt");
tag_constant!(SEALED_MESSAGE, 40019, "crypto-sealed");
tag_constant!(SIGNATURE, 40020, "signature");
tag_constant!(SIGNING_PRIVATE_KEY, 40021, "signing-private-key");
tag_constant!(SIGNING_PUBLIC_KEY, 40022, "signing-public-key");
tag_constant!(SYMMETRIC_KEY, 40023, "crypto-key");
tag_constant!(HDKEY, 303, "crypto-hdkey"); tag_constant!(DERIVATION_PATH, 304, "crypto-keypath"); tag_constant!(USE_INFO, 305, "crypto-coin-info"); tag_constant!(ADDRESS, 307, "crypto-address"); tag_constant!(PSBT, 310, "crypto-psbt"); tag_constant!(ACCOUNT, 311, "crypto-account"); tag_constant!(OUTPUT, 308, "crypto-output"); tag_constant!(OUTPUT_SCRIPT_HASH, 400, "output-script-hash"); tag_constant!(OUTPUT_WITNESS_SCRIPT_HASH, 401, "output-witness-script-hash"); tag_constant!(OUTPUT_PUBLIC_KEY, 402, "output-public-key"); tag_constant!(OUTPUT_PUBLIC_KEY_HASH, 403, "output-public-key-hash"); tag_constant!(OUTPUT_WITNESS_PUBLIC_KEY_HASH, 404, "output-witness-public-key-hash"); tag_constant!(OUTPUT_COMBO, 405, "output-combo"); tag_constant!(OUTPUT_MULTISIG, 406, "output-multisig"); tag_constant!(OUTPUT_SORTED_MULTISIG, 407, "output-sorted-multisig"); tag_constant!(OUTPUT_RAW_SCRIPT, 408, "output-raw-script"); tag_constant!(OUTPUT_TAPROOT, 409, "output-taproot"); tag_constant!(OUTPUT_COSIGNER, 410, "output-cosigner"); tag_constant!(OUTPUT_DESCRIPTOR_RESPONSE, 500, "output-descriptor-response"); pub struct LazyTagsStore {
init: Once,
data: Mutex<Option<TagsStore>>,
}
impl LazyTagsStore {
pub fn get(&self) -> std::sync::MutexGuard<'_, Option<TagsStore>> {
self.init.call_once(|| {
let m = TagsStore::new([
LEAF,
ENVELOPE,
KNOWN_VALUE,
DIGEST,
ENCRYPTED,
COMPRESSED,
REQUEST,
RESPONSE,
FUNCTION,
PARAMETER,
PLACEHOLDER,
REPLACEMENT,
SEED,
AGREEMENT_PRIVATE_KEY,
AGREEMENT_PUBLIC_KEY,
EC_KEY,
SSKR_SHARE,
CID,
SEED_DIGEST,
NONCE,
PASSWORD,
PRIVATE_KEYBASE,
PUBLIC_KEYBASE,
SALT,
SEALED_MESSAGE,
SIGNATURE,
SIGNING_PRIVATE_KEY,
SIGNING_PUBLIC_KEY,
SYMMETRIC_KEY,
HDKEY,
DERIVATION_PATH,
USE_INFO,
ADDRESS,
PSBT,
ACCOUNT,
OUTPUT,
OUTPUT_SCRIPT_HASH,
OUTPUT_WITNESS_SCRIPT_HASH,
OUTPUT_PUBLIC_KEY,
OUTPUT_PUBLIC_KEY_HASH,
OUTPUT_WITNESS_PUBLIC_KEY_HASH,
OUTPUT_COMBO,
OUTPUT_MULTISIG,
OUTPUT_SORTED_MULTISIG,
OUTPUT_RAW_SCRIPT,
OUTPUT_TAPROOT,
OUTPUT_COSIGNER,
OUTPUT_DESCRIPTOR_RESPONSE,
]);
*self.data.lock().unwrap() = Some(m);
});
self.data.lock().unwrap()
}
}
pub static GLOBAL_TAGS: LazyTagsStore = LazyTagsStore {
init: Once::new(),
data: Mutex::new(None),
};
#[macro_export]
macro_rules! with_tags {
($action:expr) => {{
let binding = $crate::GLOBAL_TAGS.get();
let tags = binding.as_ref().unwrap();
$action(tags)
}};
}
#[cfg(test)]
mod tests {
use crate::with_tags;
#[test]
fn test_1() {
use crate::*;
assert_eq!(tags::LEAF.value(), 24);
assert_eq!(tags::LEAF.name().as_ref().unwrap(), Some("leaf").unwrap());
with_tags!(|tags: &dyn dcbor::TagsStoreTrait| {
assert_eq!(tags.name_for_tag(&tags::LEAF), "leaf");
});
}
}