1use std::sync::Arc;
4
5macro_rules! wrapped_string {
7 ($wrapper:ident, $name:expr) => {
8 impl $wrapper {
9 #[doc = "Create a"]
10 #[doc = $name]
11 #[doc = ".\n\n"]
12 #[doc = "## Precondition\n\n"]
13 #[doc = "The string must be a valid"]
14 #[doc = $name]
15 #[doc = ".\n\n"]
16 #[doc = "## Panics\n\n"]
17 #[doc = "Panics may occur down the line if the precondition is not satisfied."]
18 pub fn from_str_unchecked(s: &str) -> Self {
19 Self(Arc::from(s))
20 }
21
22 pub fn as_inner(&self) -> &str {
24 self.0.as_ref()
25 }
26
27 pub fn shallow_clone(&self) -> Self {
29 Self(Arc::clone(&self.0))
30 }
31 }
32
33 impl std::fmt::Display for $wrapper {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 std::fmt::Display::fmt(&self.0, f)
36 }
37 }
38
39 impl std::fmt::Debug for $wrapper {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 std::fmt::Display::fmt(&self.0, f)
42 }
43 }
44 };
45}
46
47macro_rules! impl_arbitrary_lowercase_alpha {
54 ($wrapper:ident) => {
55 #[cfg(feature = "arbitrary")]
56 impl<'a> arbitrary::Arbitrary<'a> for $wrapper {
57 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
58 let len = u.int_in_range(1..=10)?;
59 let mut string = String::with_capacity(len);
60 for _ in 0..len {
61 let offset = u.int_in_range(0..=25)?;
62 string.push((b'a' + offset) as char)
63 }
64 Ok(Self::from_str_unchecked(string.as_str()))
65 }
66 }
67 };
68}
69
70#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
72pub struct FunctionName(Arc<str>);
73
74impl FunctionName {
75 pub fn main() -> Self {
77 Self(Arc::from("main"))
78 }
79}
80
81wrapped_string!(FunctionName, "function name");
82
83#[cfg(feature = "arbitrary")]
84impl<'a> arbitrary::Arbitrary<'a> for FunctionName {
85 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
86 const RESERVED_NAMES: [&str; 11] = [
87 "unwrap_left",
88 "unwrap_right",
89 "for_while",
90 "is_none",
91 "unwrap",
92 "assert",
93 "panic",
94 "match",
95 "into",
96 "fold",
97 "dbg",
98 ];
99
100 let len = u.int_in_range(1..=10)?;
101 let mut string = String::with_capacity(len);
102 for _ in 0..len {
103 let offset = u.int_in_range(0..=25)?;
104 string.push((b'a' + offset) as char)
105 }
106 if RESERVED_NAMES.contains(&string.as_str()) {
107 string.push('_');
108 }
109
110 Ok(Self::from_str_unchecked(string.as_str()))
111 }
112}
113
114#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
116pub struct Identifier(Arc<str>);
117
118wrapped_string!(Identifier, "variable identifier");
119impl_arbitrary_lowercase_alpha!(Identifier);
120
121#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
123pub struct WitnessName(Arc<str>);
124
125wrapped_string!(WitnessName, "witness name");
126impl_arbitrary_lowercase_alpha!(WitnessName);
127
128#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
130pub struct JetName(Arc<str>);
131
132wrapped_string!(JetName, "jet name");
133
134#[cfg(feature = "arbitrary")]
135impl<'a> arbitrary::Arbitrary<'a> for JetName {
136 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
137 u.choose(&simplicity::jet::Elements::ALL)
138 .map(simplicity::jet::Elements::to_string)
139 .map(Arc::from)
140 .map(Self)
141 }
142}
143
144#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
146pub struct AliasName(Arc<str>);
147
148wrapped_string!(AliasName, "name of a type alias");
149
150#[cfg(feature = "arbitrary")]
151impl<'a> arbitrary::Arbitrary<'a> for AliasName {
152 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
153 const RESERVED_NAMES: [&str; 37] = [
154 "Either",
155 "Option",
156 "bool",
157 "List",
158 "u128",
159 "u256",
160 "u16",
161 "u32",
162 "u64",
163 "u1",
164 "u2",
165 "u4",
166 "u8",
167 "Ctx8",
168 "Pubkey",
169 "Message64",
170 "Message",
171 "Signature",
172 "Scalar",
173 "Fe",
174 "Gej",
175 "Ge",
176 "Point",
177 "Height",
178 "Time",
179 "Distance",
180 "Duration",
181 "Lock",
182 "Outpoint",
183 "Confidential1",
184 "ExplicitAsset",
185 "Asset1",
186 "ExplicitAmount",
187 "Amount1",
188 "ExplicitNonce",
189 "Nonce",
190 "TokenAmount1",
191 ];
192
193 let len = u.int_in_range(1..=10)?;
194 let mut string = String::with_capacity(len);
195 for _ in 0..len {
196 let offset = u.int_in_range(0..=25)?;
197 string.push((b'a' + offset) as char)
198 }
199 if RESERVED_NAMES.contains(&string.as_str()) {
200 string.push('_');
201 }
202
203 Ok(Self::from_str_unchecked(string.as_str()))
204 }
205}
206
207#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
209pub struct Decimal(Arc<str>);
210
211wrapped_string!(Decimal, "decimal string");
212
213#[cfg(feature = "arbitrary")]
214impl<'a> arbitrary::Arbitrary<'a> for Decimal {
215 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
216 let len = u.int_in_range(1..=10)?;
217 let mut string = String::with_capacity(len);
218 for _ in 0..len {
219 let offset = u.int_in_range(0..=9)?;
220 string.push((b'0' + offset) as char)
221 }
222 Ok(Self::from_str_unchecked(string.as_str()))
223 }
224}
225
226#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
228pub struct Binary(Arc<str>);
229
230wrapped_string!(Binary, "binary string");
231
232#[cfg(feature = "arbitrary")]
233impl<'a> arbitrary::Arbitrary<'a> for Binary {
234 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
235 let len = u.int_in_range(1..=10)?;
236 let mut string = String::with_capacity(len);
237 for _ in 0..len {
238 let offset = u.int_in_range(0..=1)?;
239 let bin_digit = (b'0' + offset) as char;
240 string.push(bin_digit);
241 }
242 Ok(Self::from_str_unchecked(string.as_str()))
243 }
244}
245
246#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
248pub struct Hexadecimal(Arc<str>);
249
250wrapped_string!(Hexadecimal, "hexadecimal string");
251
252#[cfg(feature = "arbitrary")]
253impl<'a> arbitrary::Arbitrary<'a> for Hexadecimal {
254 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
255 let len = u.int_in_range(1..=10)?;
256 let mut string = String::with_capacity(len);
257 for _ in 0..len {
258 let offset = u.int_in_range(0..=15)?;
259 let hex_digit = match offset {
260 0..=9 => (b'0' + offset) as char,
261 10..=15 => (b'a' + (offset - 10)) as char,
262 _ => unreachable!(),
263 };
264 string.push(hex_digit);
265 }
266 Ok(Self::from_str_unchecked(string.as_str()))
267 }
268}
269
270#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
272pub struct ModuleName(Arc<str>);
273
274impl ModuleName {
275 pub fn witness() -> Self {
277 Self(Arc::from("witness"))
278 }
279
280 pub fn param() -> Self {
282 Self(Arc::from("param"))
283 }
284}
285
286wrapped_string!(ModuleName, "module name");