1use crate::{
2 AbiItem, Constructor, Error, Event, Fallback, Function, Receive,
3 to_sol::{SolPrinter, ToSolConfig},
4};
5use alloc::{collections::btree_map, string::String, vec::Vec};
6use alloy_primitives::{Bytes, Selector};
7use btree_map::BTreeMap;
8use core::{fmt, iter, iter::Flatten};
9use serde::{
10 Deserialize, Deserializer, Serialize,
11 de::{MapAccess, SeqAccess, Visitor},
12 ser::SerializeSeq,
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 function_by_selector(&self, selector: Selector) -> Option<&Function> {
300 self.functions().find(|func| func.selector() == selector)
301 }
302
303 #[inline]
305 pub fn events(&self) -> FlattenValues<'_, Event> {
306 self.events.values().flatten()
307 }
308
309 #[inline]
311 pub fn events_mut(&mut self) -> FlattenValuesMut<'_, Event> {
312 self.events.values_mut().flatten()
313 }
314
315 #[inline]
317 pub fn errors(&self) -> FlattenValues<'_, Error> {
318 self.errors.values().flatten()
319 }
320
321 #[inline]
323 pub fn errors_mut(&mut self) -> FlattenValuesMut<'_, Error> {
324 self.errors.values_mut().flatten()
325 }
326
327 fn insert_item(&mut self, item: AbiItem<'_>) -> Result<(), &'static str> {
329 match item {
330 AbiItem::Constructor(c) => set_if_none!(self.constructor, c.into_owned()),
331 AbiItem::Fallback(f) => set_if_none!(self.fallback, f.into_owned()),
332 AbiItem::Receive(r) => set_if_none!(self.receive, r.into_owned()),
333 AbiItem::Function(f) => entry_and_push!(self.functions, f),
334 AbiItem::Event(e) => entry_and_push!(self.events, e),
335 AbiItem::Error(e) => entry_and_push!(self.errors, e),
336 };
337 Ok(())
338 }
339}
340
341macro_rules! next_item {
342 ($self:ident; $($ident:ident.$f:ident()),* $(,)?) => {$(
343 if let Some(next) = $self.$ident.$f() {
344 $self.len -= 1;
345 return Some(next.into())
346 }
347 )*};
348}
349
350macro_rules! iter_impl {
351 (front) => {
352 fn next(&mut self) -> Option<Self::Item> {
353 next_item!(self;
354 constructor.take(),
355 fallback.take(),
356 receive.take(),
357 functions.next(),
358 events.next(),
359 errors.next(),
360 );
361 debug_assert_eq!(self.len, 0);
362 None
363 }
364
365 #[inline]
366 fn count(self) -> usize {
367 self.len
368 }
369
370 #[inline]
371 fn last(mut self) -> Option<Self::Item> {
372 self.next_back()
373 }
374
375 #[inline]
376 fn size_hint(&self) -> (usize, Option<usize>) {
377 (self.len, Some(self.len))
378 }
379 };
380 (back) => {
381 fn next_back(&mut self) -> Option<Self::Item> {
382 next_item!(self;
383 errors.next_back(),
384 events.next_back(),
385 functions.next_back(),
386 receive.take(),
387 fallback.take(),
388 constructor.take(),
389 );
390 debug_assert_eq!(self.len, 0);
391 None
392 }
393 };
394 (traits $ty:ty) => {
395 impl DoubleEndedIterator for $ty {
396 iter_impl!(back);
397 }
398
399 impl ExactSizeIterator for $ty {
400 #[inline]
401 fn len(&self) -> usize {
402 self.len
403 }
404 }
405
406 impl iter::FusedIterator for $ty {}
407 };
408}
409
410#[derive(Clone, Debug, Default)]
415pub struct Items<'a> {
416 len: usize,
417 constructor: Option<&'a Constructor>,
418 fallback: Option<&'a Fallback>,
419 receive: Option<&'a Receive>,
420 functions: FlattenValues<'a, Function>,
421 events: FlattenValues<'a, Event>,
422 errors: FlattenValues<'a, Error>,
423}
424
425impl<'a> Iterator for Items<'a> {
426 type Item = AbiItem<'a>;
427
428 iter_impl!(front);
429}
430
431iter_impl!(traits Items<'_>);
432
433#[derive(Debug, Default)]
438pub struct IntoItems {
439 len: usize,
440 constructor: Option<Constructor>,
441 fallback: Option<Fallback>,
442 receive: Option<Receive>,
443 functions: FlattenIntoValues<Function>,
444 events: FlattenIntoValues<Event>,
445 errors: FlattenIntoValues<Error>,
446}
447
448impl Iterator for IntoItems {
449 type Item = AbiItem<'static>;
450
451 iter_impl!(front);
452}
453
454iter_impl!(traits IntoItems);
455
456impl<'de> Deserialize<'de> for JsonAbi {
457 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
458 deserializer.deserialize_seq(JsonAbiVisitor)
459 }
460}
461
462impl Serialize for JsonAbi {
463 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
464 let len = self.len();
465 let mut seq = serializer.serialize_seq(Some(len))?;
466 for item in self.items_with_len(len) {
467 seq.serialize_element(&item)?;
468 }
469 seq.end()
470 }
471}
472
473struct JsonAbiVisitor;
474
475impl<'de> Visitor<'de> for JsonAbiVisitor {
476 type Value = JsonAbi;
477
478 #[inline]
479 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
480 f.write_str("a valid JSON ABI sequence")
481 }
482
483 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
484 let mut abi = JsonAbi::new();
485 while let Some(item) = seq.next_element()? {
486 abi.insert_item(item).map_err(serde::de::Error::duplicate_field)?;
487 }
488 Ok(abi)
489 }
490}
491
492#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize)]
497#[serde(rename_all = "camelCase")]
498pub struct ContractObject {
499 #[serde(default, skip_serializing_if = "Option::is_none")]
501 pub abi: Option<JsonAbi>,
502 #[serde(default, skip_serializing_if = "Option::is_none")]
504 pub bytecode: Option<Bytes>,
505 #[serde(default, skip_serializing_if = "Option::is_none")]
507 pub deployed_bytecode: Option<Bytes>,
508}
509
510impl<'de> Deserialize<'de> for ContractObject {
511 #[inline]
512 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
513 deserializer.deserialize_any(ContractObjectVisitor::default())
514 }
515}
516
517#[cfg(feature = "serde_json")]
518impl ContractObject {
519 pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
524 Self::from_json_with(s, true)
525 }
526
527 pub fn from_json_with(
531 s: &str,
532 ignore_unlinked_bytecode: bool,
533 ) -> Result<Self, serde_json::Error> {
534 let visitor = ContractObjectVisitor { ignore_unlinked_bytecode };
535 serde_json::Deserializer::from_str(s).deserialize_any(visitor)
536 }
537}
538#[derive(Default)]
541struct ContractObjectVisitor {
542 ignore_unlinked_bytecode: bool,
544}
545
546impl<'de> Visitor<'de> for ContractObjectVisitor {
547 type Value = ContractObject;
548
549 #[inline]
550 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
551 f.write_str("an ABI sequence or contract object")
552 }
553
554 #[inline]
555 fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
556 JsonAbiVisitor.visit_seq(seq).map(|abi| ContractObject {
557 abi: Some(abi),
558 bytecode: None,
559 deployed_bytecode: None,
560 })
561 }
562
563 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
564 #[derive(Deserialize)]
565 #[serde(untagged)]
566 enum Bytecode {
567 Bytes(Bytes),
568 Object { object: Bytes },
569 Unlinked(String),
570 UnlinkedObject { object: String },
571 }
572
573 impl Bytecode {
574 fn ensure_bytes<E: serde::de::Error>(
575 self,
576 ignore_unlinked_bytecode: bool,
577 ) -> Result<Option<Bytes>, E> {
578 match self {
579 Bytecode::Bytes(bytes) | Bytecode::Object { object: bytes } => Ok(Some(bytes)),
580 Bytecode::Unlinked(unlinked)
581 | Bytecode::UnlinkedObject { object: unlinked } => {
582 if ignore_unlinked_bytecode {
583 return Ok(None);
584 }
585 if let Some((_, unlinked)) = unlinked.split_once("__$") {
586 if let Some((addr, _)) = unlinked.split_once("$__") {
587 return Err(E::custom(format!(
588 "expected bytecode, found unlinked bytecode with placeholder: {addr}. Use the `ignore_unlinked` sol attribute to bypass this error."
589 )));
590 }
591 }
592 Err(E::custom("invalid contract bytecode"))
593 }
594 }
595 }
596 }
597
598 #[derive(Deserialize)]
600 struct EvmObj {
601 bytecode: Option<Bytecode>,
602 #[serde(rename = "deployedBytecode")]
603 deployed_bytecode: Option<Bytecode>,
604 }
605
606 let mut abi = None;
607 let mut bytecode = None;
608 let mut deployed_bytecode = None;
609
610 while let Some(key) = map.next_key::<&str>()? {
611 match key {
612 "abi" => set_if_none!(@serde abi, map.next_value()?),
613 "evm" => {
614 let evm = map.next_value::<EvmObj>()?;
615 if let Some(bytes) = evm.bytecode {
616 if let Some(b) = bytes.ensure_bytes(self.ignore_unlinked_bytecode)? {
617 set_if_none!(@serde bytecode, b);
618 }
619 }
620 if let Some(bytes) = evm.deployed_bytecode {
621 if let Some(b) = bytes.ensure_bytes(self.ignore_unlinked_bytecode)? {
622 set_if_none!(@serde deployed_bytecode, b);
623 }
624 }
625 }
626 "bytecode" | "bin" => {
627 if let Some(b) =
628 map.next_value::<Bytecode>()?.ensure_bytes(self.ignore_unlinked_bytecode)?
629 {
630 set_if_none!(@serde bytecode, b);
631 }
632 }
633 "deployedBytecode" | "deployedbytecode" | "deployed_bytecode" | "runtimeBin"
634 | "runtimebin" | "runtime " => {
635 if let Some(b) =
636 map.next_value::<Bytecode>()?.ensure_bytes(self.ignore_unlinked_bytecode)?
637 {
638 set_if_none!(@serde deployed_bytecode, b);
639 }
640 }
641 _ => {
642 map.next_value::<serde::de::IgnoredAny>()?;
643 }
644 }
645 }
646
647 Ok(ContractObject { abi, bytecode, deployed_bytecode })
648 }
649}