1use crate::{
2 to_sol::{SolPrinter, ToSolConfig},
3 AbiItem, Constructor, Error, Event, Fallback, Function, Receive,
4};
5use alloc::{collections::btree_map, string::String, vec::Vec};
6use alloy_primitives::Bytes;
7use btree_map::BTreeMap;
8use core::{fmt, iter, iter::Flatten};
9use serde::{
10 de::{MapAccess, SeqAccess, Visitor},
11 ser::SerializeSeq,
12 Deserialize, Deserializer, Serialize,
13};
14
15macro_rules! set_if_none {
16 ($opt:expr, $val:expr) => { set_if_none!(stringify!($opt) => $opt, $val) };
17 (@serde $opt:expr, $val:expr) => { set_if_none!(serde::de::Error::duplicate_field(stringify!($opt)) => $opt, $val) };
18 ($name:expr => $opt:expr, $val:expr) => {{
19 if $opt.is_some() {
20 return Err($name)
21 }
22 $opt = Some($val);
23 }};
24}
25
26macro_rules! entry_and_push {
27 ($map:expr, $v:expr) => {
28 $map.entry($v.name.clone()).or_default().push($v.into_owned())
29 };
30}
31
32type FlattenValues<'a, V> = Flatten<btree_map::Values<'a, String, Vec<V>>>;
33type FlattenValuesMut<'a, V> = Flatten<btree_map::ValuesMut<'a, String, Vec<V>>>;
34type FlattenIntoValues<V> = Flatten<btree_map::IntoValues<String, Vec<V>>>;
35
36#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
40pub struct JsonAbi {
41 pub constructor: Option<Constructor>,
43 pub fallback: Option<Fallback>,
45 pub receive: Option<Receive>,
47 pub functions: BTreeMap<String, Vec<Function>>,
49 pub events: BTreeMap<String, Vec<Event>>,
51 pub errors: BTreeMap<String, Vec<Error>>,
53}
54
55impl<'a> FromIterator<AbiItem<'a>> for JsonAbi {
56 fn from_iter<T: IntoIterator<Item = AbiItem<'a>>>(iter: T) -> Self {
57 let mut abi = Self::new();
58 for item in iter {
59 let _ = abi.insert_item(item);
60 }
61 abi
62 }
63}
64
65impl JsonAbi {
66 #[inline]
68 pub fn new() -> Self {
69 Self::default()
70 }
71
72 pub fn parse<'a, I: IntoIterator<Item = &'a str>>(strings: I) -> parser::Result<Self> {
97 let mut abi = Self::new();
98 for string in strings {
99 let item = AbiItem::parse(string)?;
100 abi.insert_item(item)
101 .map_err(|s| parser::Error::_new("duplicate JSON ABI field: ", &s))?;
102 }
103 Ok(abi)
104 }
105
106 #[cfg(feature = "serde_json")]
110 #[inline]
111 pub fn from_json_str(json: &str) -> Result<Self, serde_json::Error> {
112 serde_json::from_str(json)
113 }
114
115 #[cfg(all(feature = "std", feature = "serde_json"))]
119 pub fn load<T: std::io::Read>(mut reader: T) -> Result<Self, serde_json::Error> {
120 let mut json = String::with_capacity(1024);
124 reader.read_to_string(&mut json).map_err(serde_json::Error::io)?;
125
126 Self::from_json_str(&json)
127 }
128
129 pub fn len(&self) -> usize {
131 self.constructor.is_some() as usize
132 + self.fallback.is_some() as usize
133 + self.receive.is_some() as usize
134 + self.functions.values().map(Vec::len).sum::<usize>()
135 + self.events.values().map(Vec::len).sum::<usize>()
136 + self.errors.values().map(Vec::len).sum::<usize>()
137 }
138
139 #[inline]
141 pub fn is_empty(&self) -> bool {
142 self.len() == 0
143 }
144
145 #[inline]
147 pub fn items(&self) -> Items<'_> {
148 self.items_with_len(self.len())
149 }
150
151 #[inline]
153 fn items_with_len(&self, len: usize) -> Items<'_> {
154 Items {
155 len,
156 constructor: self.constructor.as_ref(),
157 fallback: self.fallback.as_ref(),
158 receive: self.receive.as_ref(),
159 functions: self.functions(),
160 events: self.events(),
161 errors: self.errors(),
162 }
163 }
164
165 #[inline]
167 pub fn into_items(self) -> IntoItems {
168 IntoItems {
169 len: self.len(),
170 constructor: self.constructor,
171 fallback: self.fallback,
172 receive: self.receive,
173 functions: self.functions.into_values().flatten(),
174 events: self.events.into_values().flatten(),
175 errors: self.errors.into_values().flatten(),
176 }
177 }
178
179 #[inline]
201 pub fn to_sol(&self, name: &str, config: Option<ToSolConfig>) -> String {
202 let mut out = String::new();
203 self.to_sol_raw(name, &mut out, config);
204 out
205 }
206
207 pub fn to_sol_raw(&self, name: &str, out: &mut String, config: Option<ToSolConfig>) {
211 out.reserve(self.len() * 128);
212 SolPrinter::new(out, name, config.unwrap_or_default()).print(self);
213 }
214
215 pub fn dedup(&mut self) {
217 macro_rules! same_bucket {
218 () => {
219 |a, b| {
220 debug_assert_eq!(a.name, b.name);
222 a.inputs == b.inputs
223 }
224 };
225 }
226 for functions in self.functions.values_mut() {
227 functions.dedup_by(same_bucket!());
228 }
229 for errors in self.errors.values_mut() {
230 errors.dedup_by(same_bucket!());
231 }
232 for events in self.events.values_mut() {
233 events.dedup_by(same_bucket!());
234 }
235 }
236
237 #[inline]
239 pub const fn constructor(&self) -> Option<&Constructor> {
240 self.constructor.as_ref()
241 }
242
243 #[inline]
245 pub fn constructor_mut(&mut self) -> Option<&mut Constructor> {
246 self.constructor.as_mut()
247 }
248
249 #[inline]
251 pub fn function(&self, name: &str) -> Option<&Vec<Function>> {
252 self.functions.get(name)
253 }
254
255 #[inline]
257 pub fn function_mut(&mut self, name: &str) -> Option<&mut Vec<Function>> {
258 self.functions.get_mut(name)
259 }
260
261 #[inline]
263 pub fn event(&self, name: &str) -> Option<&Vec<Event>> {
264 self.events.get(name)
265 }
266
267 #[inline]
269 pub fn event_mut(&mut self, name: &str) -> Option<&mut Vec<Event>> {
270 self.events.get_mut(name)
271 }
272
273 #[inline]
275 pub fn error(&self, name: &str) -> Option<&Vec<Error>> {
276 self.errors.get(name)
277 }
278
279 #[inline]
281 pub fn error_mut(&mut self, name: &str) -> Option<&mut Vec<Error>> {
282 self.errors.get_mut(name)
283 }
284
285 #[inline]
287 pub fn functions(&self) -> FlattenValues<'_, Function> {
288 self.functions.values().flatten()
289 }
290
291 #[inline]
293 pub fn functions_mut(&mut self) -> FlattenValuesMut<'_, Function> {
294 self.functions.values_mut().flatten()
295 }
296
297 #[inline]
299 pub fn events(&self) -> FlattenValues<'_, Event> {
300 self.events.values().flatten()
301 }
302
303 #[inline]
305 pub fn events_mut(&mut self) -> FlattenValuesMut<'_, Event> {
306 self.events.values_mut().flatten()
307 }
308
309 #[inline]
311 pub fn errors(&self) -> FlattenValues<'_, Error> {
312 self.errors.values().flatten()
313 }
314
315 #[inline]
317 pub fn errors_mut(&mut self) -> FlattenValuesMut<'_, Error> {
318 self.errors.values_mut().flatten()
319 }
320
321 fn insert_item(&mut self, item: AbiItem<'_>) -> Result<(), &'static str> {
323 match item {
324 AbiItem::Constructor(c) => set_if_none!(self.constructor, c.into_owned()),
325 AbiItem::Fallback(f) => set_if_none!(self.fallback, f.into_owned()),
326 AbiItem::Receive(r) => set_if_none!(self.receive, r.into_owned()),
327 AbiItem::Function(f) => entry_and_push!(self.functions, f),
328 AbiItem::Event(e) => entry_and_push!(self.events, e),
329 AbiItem::Error(e) => entry_and_push!(self.errors, e),
330 };
331 Ok(())
332 }
333}
334
335macro_rules! next_item {
336 ($self:ident; $($ident:ident.$f:ident()),* $(,)?) => {$(
337 if let Some(next) = $self.$ident.$f() {
338 $self.len -= 1;
339 return Some(next.into())
340 }
341 )*};
342}
343
344macro_rules! iter_impl {
345 (front) => {
346 fn next(&mut self) -> Option<Self::Item> {
347 next_item!(self;
348 constructor.take(),
349 fallback.take(),
350 receive.take(),
351 functions.next(),
352 events.next(),
353 errors.next(),
354 );
355 debug_assert_eq!(self.len, 0);
356 None
357 }
358
359 #[inline]
360 fn count(self) -> usize {
361 self.len
362 }
363
364 #[inline]
365 fn last(mut self) -> Option<Self::Item> {
366 self.next_back()
367 }
368
369 #[inline]
370 fn size_hint(&self) -> (usize, Option<usize>) {
371 (self.len, Some(self.len))
372 }
373 };
374 (back) => {
375 fn next_back(&mut self) -> Option<Self::Item> {
376 next_item!(self;
377 errors.next_back(),
378 events.next_back(),
379 functions.next_back(),
380 receive.take(),
381 fallback.take(),
382 constructor.take(),
383 );
384 debug_assert_eq!(self.len, 0);
385 None
386 }
387 };
388 (traits $ty:ty) => {
389 impl DoubleEndedIterator for $ty {
390 iter_impl!(back);
391 }
392
393 impl ExactSizeIterator for $ty {
394 #[inline]
395 fn len(&self) -> usize {
396 self.len
397 }
398 }
399
400 impl iter::FusedIterator for $ty {}
401 };
402}
403
404#[derive(Clone, Debug, Default)]
409pub struct Items<'a> {
410 len: usize,
411 constructor: Option<&'a Constructor>,
412 fallback: Option<&'a Fallback>,
413 receive: Option<&'a Receive>,
414 functions: FlattenValues<'a, Function>,
415 events: FlattenValues<'a, Event>,
416 errors: FlattenValues<'a, Error>,
417}
418
419impl<'a> Iterator for Items<'a> {
420 type Item = AbiItem<'a>;
421
422 iter_impl!(front);
423}
424
425iter_impl!(traits Items<'_>);
426
427#[derive(Debug, Default)]
432pub struct IntoItems {
433 len: usize,
434 constructor: Option<Constructor>,
435 fallback: Option<Fallback>,
436 receive: Option<Receive>,
437 functions: FlattenIntoValues<Function>,
438 events: FlattenIntoValues<Event>,
439 errors: FlattenIntoValues<Error>,
440}
441
442impl Iterator for IntoItems {
443 type Item = AbiItem<'static>;
444
445 iter_impl!(front);
446}
447
448iter_impl!(traits IntoItems);
449
450impl<'de> Deserialize<'de> for JsonAbi {
451 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
452 deserializer.deserialize_seq(JsonAbiVisitor)
453 }
454}
455
456impl Serialize for JsonAbi {
457 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
458 let len = self.len();
459 let mut seq = serializer.serialize_seq(Some(len))?;
460 for item in self.items_with_len(len) {
461 seq.serialize_element(&item)?;
462 }
463 seq.end()
464 }
465}
466
467struct JsonAbiVisitor;
468
469impl<'de> Visitor<'de> for JsonAbiVisitor {
470 type Value = JsonAbi;
471
472 #[inline]
473 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
474 f.write_str("a valid JSON ABI sequence")
475 }
476
477 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
478 let mut abi = JsonAbi::new();
479 while let Some(item) = seq.next_element()? {
480 abi.insert_item(item).map_err(serde::de::Error::duplicate_field)?;
481 }
482 Ok(abi)
483 }
484}
485
486#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize)]
491#[serde(rename_all = "camelCase")]
492pub struct ContractObject {
493 #[serde(default, skip_serializing_if = "Option::is_none")]
495 pub abi: Option<JsonAbi>,
496 #[serde(default, skip_serializing_if = "Option::is_none")]
498 pub bytecode: Option<Bytes>,
499 #[serde(default, skip_serializing_if = "Option::is_none")]
501 pub deployed_bytecode: Option<Bytes>,
502}
503
504impl<'de> Deserialize<'de> for ContractObject {
505 #[inline]
506 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
507 deserializer.deserialize_any(ContractObjectVisitor)
508 }
509}
510
511struct ContractObjectVisitor;
514
515impl<'de> Visitor<'de> for ContractObjectVisitor {
516 type Value = ContractObject;
517
518 #[inline]
519 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
520 f.write_str("an ABI sequence or contract object")
521 }
522
523 #[inline]
524 fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
525 JsonAbiVisitor.visit_seq(seq).map(|abi| ContractObject {
526 abi: Some(abi),
527 bytecode: None,
528 deployed_bytecode: None,
529 })
530 }
531
532 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
533 #[derive(Deserialize)]
534 #[serde(untagged)]
535 enum Bytecode {
536 Bytes(Bytes),
537 Object { object: Bytes },
538 Unlinked(String),
539 UnlinkedObject { object: String },
540 }
541
542 impl Bytecode {
543 fn ensure_bytes<E: serde::de::Error>(self) -> Result<Bytes, E> {
544 match self {
545 Bytecode::Bytes(bytes) | Bytecode::Object { object: bytes } => Ok(bytes),
546 Bytecode::Unlinked(unlinked)
547 | Bytecode::UnlinkedObject { object: unlinked } => {
548 if let Some((_, unlinked)) = unlinked.split_once("__$") {
549 if let Some((addr, _)) = unlinked.split_once("$__") {
550 return Err(E::custom(format!("expected bytecode, found unlinked bytecode with placeholder: {addr}")));
551 }
552 }
553 Err(E::custom("invalid contract bytecode"))
554 }
555 }
556 }
557 }
558
559 #[derive(Deserialize)]
561 struct EvmObj {
562 bytecode: Option<Bytecode>,
563 #[serde(rename = "deployedBytecode")]
564 deployed_bytecode: Option<Bytecode>,
565 }
566
567 let mut abi = None;
568 let mut bytecode = None;
569 let mut deployed_bytecode = None;
570
571 while let Some(key) = map.next_key::<&str>()? {
572 match key {
573 "abi" => set_if_none!(@serde abi, map.next_value()?),
574 "evm" => {
575 let evm = map.next_value::<EvmObj>()?;
576 if let Some(bytes) = evm.bytecode {
577 set_if_none!(@serde bytecode, bytes.ensure_bytes()?);
578 }
579 if let Some(bytes) = evm.deployed_bytecode {
580 set_if_none!(@serde deployed_bytecode, bytes.ensure_bytes()?);
581 }
582 }
583 "bytecode" | "bin" => {
584 set_if_none!(@serde bytecode, map.next_value::<Bytecode>()?.ensure_bytes()?);
585 }
586 "deployedBytecode" | "deployedbytecode" | "deployed_bytecode" | "runtimeBin"
587 | "runtimebin" | "runtime " => {
588 set_if_none!(@serde deployed_bytecode, map.next_value::<Bytecode>()?.ensure_bytes()?);
589 }
590 _ => {
591 map.next_value::<serde::de::IgnoredAny>()?;
592 }
593 }
594 }
595
596 Ok(ContractObject { abi, bytecode, deployed_bytecode })
597 }
598}