1#[derive(Debug, Eq, PartialEq)]
5pub(crate) struct Encoding {
6 pub hash_scheme: &'static str,
8
9 pub public_key_scheme: &'static str,
11
12 pub secret_key_scheme: &'static str,
14
15 pub signature_scheme: &'static str,
17
18 pub delimiter: char,
20
21 pub combine: char,
23
24 pub fragment_delimiter: Option<char>,
26}
27
28pub(crate) const URI_ENCODING: &Encoding = &Encoding {
32 hash_scheme: "crypto:hash:",
33 public_key_scheme: "crypto:pub:key:",
34 secret_key_scheme: "crypto:sec:key:",
35 signature_scheme: "crypto:sig:",
36 delimiter: ':',
37 combine: '+',
38 fragment_delimiter: Some('#'),
39};
40
41pub(crate) const DASHERIZED_ENCODING: &Encoding = &Encoding {
43 hash_scheme: "crypto-hash-",
44 public_key_scheme: "crypto-pub-key-",
45 secret_key_scheme: "crypto-sec-key-",
46 signature_scheme: "crypto-sig-",
47 delimiter: '-',
48 combine: '_',
49 fragment_delimiter: None,
50};
51
52pub trait Encodable {
54 fn to_uri_string(&self) -> String;
56
57 fn to_dasherized_string(&self) -> String;
59}
60
61macro_rules! impl_encodable {
62 ($scheme:ident, $name:ident, $alg:expr) => {
63 impl crate::encoding::Encodable for $name {
64 #[inline]
65 fn to_uri_string(&self) -> String {
66 use subtle_encoding::bech32::{self, Bech32};
67 Bech32::new(
68 bech32::DEFAULT_CHARSET,
69 $crate::encoding::URI_ENCODING.delimiter,
70 )
71 .encode(
72 $crate::encoding::URI_ENCODING.$scheme.to_owned() + $alg,
73 &self.0[..],
74 )
75 }
76
77 #[inline]
78 fn to_dasherized_string(&self) -> String {
79 use subtle_encoding::bech32::{self, Bech32};
80 Bech32::new(
81 bech32::DEFAULT_CHARSET,
82 $crate::encoding::DASHERIZED_ENCODING.delimiter,
83 )
84 .encode(
85 $crate::encoding::DASHERIZED_ENCODING.$scheme.to_owned() + $alg,
86 &self.0[..],
87 )
88 }
89 }
90 };
91}
92
93macro_rules! impl_encodable_hash {
94 ($name:ident, $alg:expr) => {
95 impl_encodable!(hash_scheme, $name, $alg);
96 };
97}
98
99macro_rules! impl_encodable_public_key {
100 ($name:ident, $alg:expr) => {
101 impl_encodable!(public_key_scheme, $name, $alg);
102 };
103}
104
105macro_rules! impl_encodable_secret_key {
106 ($name:ident, $alg:expr) => {
107 impl crate::encoding::Encodable for $name {
108 #[inline]
109 fn to_uri_string(&self) -> String {
110 use secrecy::ExposeSecret;
111 use subtle_encoding::bech32::{self, Bech32};
112 Bech32::new(
113 bech32::DEFAULT_CHARSET,
114 $crate::encoding::URI_ENCODING.delimiter,
115 )
116 .encode(
117 $crate::encoding::URI_ENCODING.secret_key_scheme.to_owned() + $alg,
118 &self.expose_secret()[..],
119 )
120 }
121
122 #[inline]
123 fn to_dasherized_string(&self) -> String {
124 use secrecy::ExposeSecret;
125 use subtle_encoding::bech32::{self, Bech32};
126 Bech32::new(
127 bech32::DEFAULT_CHARSET,
128 $crate::encoding::DASHERIZED_ENCODING.delimiter,
129 )
130 .encode(
131 $crate::encoding::DASHERIZED_ENCODING
132 .secret_key_scheme
133 .to_owned()
134 + $alg,
135 &self.expose_secret()[..],
136 )
137 }
138 }
139 };
140}
141
142macro_rules! impl_encodable_signature {
143 ($name:ident, $alg:expr) => {
144 impl_encodable!(signature_scheme, $name, $alg);
145 };
146}