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::default())
508 }
509}
510
511#[cfg(feature = "serde_json")]
512impl ContractObject {
513 pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
518 Self::from_json_with(s, true)
519 }
520
521 pub fn from_json_with(
525 s: &str,
526 ignore_unlinked_bytecode: bool,
527 ) -> Result<Self, serde_json::Error> {
528 let visitor = ContractObjectVisitor { ignore_unlinked_bytecode };
529 serde_json::Deserializer::from_str(s).deserialize_any(visitor)
530 }
531}
532#[derive(Default)]
535struct ContractObjectVisitor {
536 ignore_unlinked_bytecode: bool,
538}
539
540impl<'de> Visitor<'de> for ContractObjectVisitor {
541 type Value = ContractObject;
542
543 #[inline]
544 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
545 f.write_str("an ABI sequence or contract object")
546 }
547
548 #[inline]
549 fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
550 JsonAbiVisitor.visit_seq(seq).map(|abi| ContractObject {
551 abi: Some(abi),
552 bytecode: None,
553 deployed_bytecode: None,
554 })
555 }
556
557 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
558 #[derive(Deserialize)]
559 #[serde(untagged)]
560 enum Bytecode {
561 Bytes(Bytes),
562 Object { object: Bytes },
563 Unlinked(String),
564 UnlinkedObject { object: String },
565 }
566
567 impl Bytecode {
568 fn ensure_bytes<E: serde::de::Error>(
569 self,
570 ignore_unlinked_bytecode: bool,
571 ) -> Result<Option<Bytes>, E> {
572 match self {
573 Bytecode::Bytes(bytes) | Bytecode::Object { object: bytes } => Ok(Some(bytes)),
574 Bytecode::Unlinked(unlinked)
575 | Bytecode::UnlinkedObject { object: unlinked } => {
576 if ignore_unlinked_bytecode {
577 return Ok(None);
578 }
579 if let Some((_, unlinked)) = unlinked.split_once("__$") {
580 if let Some((addr, _)) = unlinked.split_once("$__") {
581 return Err(E::custom(format!("expected bytecode, found unlinked bytecode with placeholder: {addr}. Use the `ignore_unlinked` sol attribute to bypass this error.")));
582 }
583 }
584 Err(E::custom("invalid contract bytecode"))
585 }
586 }
587 }
588 }
589
590 #[derive(Deserialize)]
592 struct EvmObj {
593 bytecode: Option<Bytecode>,
594 #[serde(rename = "deployedBytecode")]
595 deployed_bytecode: Option<Bytecode>,
596 }
597
598 let mut abi = None;
599 let mut bytecode = None;
600 let mut deployed_bytecode = None;
601
602 while let Some(key) = map.next_key::<&str>()? {
603 match key {
604 "abi" => set_if_none!(@serde abi, map.next_value()?),
605 "evm" => {
606 let evm = map.next_value::<EvmObj>()?;
607 if let Some(bytes) = evm.bytecode {
608 if let Some(b) = bytes.ensure_bytes(self.ignore_unlinked_bytecode)? {
609 set_if_none!(@serde bytecode, b);
610 }
611 }
612 if let Some(bytes) = evm.deployed_bytecode {
613 if let Some(b) = bytes.ensure_bytes(self.ignore_unlinked_bytecode)? {
614 set_if_none!(@serde deployed_bytecode, b);
615 }
616 }
617 }
618 "bytecode" | "bin" => {
619 if let Some(b) =
620 map.next_value::<Bytecode>()?.ensure_bytes(self.ignore_unlinked_bytecode)?
621 {
622 set_if_none!(@serde bytecode, b);
623 }
624 }
625 "deployedBytecode" | "deployedbytecode" | "deployed_bytecode" | "runtimeBin"
626 | "runtimebin" | "runtime " => {
627 if let Some(b) =
628 map.next_value::<Bytecode>()?.ensure_bytes(self.ignore_unlinked_bytecode)?
629 {
630 set_if_none!(@serde deployed_bytecode, b);
631 }
632 }
633 _ => {
634 map.next_value::<serde::de::IgnoredAny>()?;
635 }
636 }
637 }
638
639 Ok(ContractObject { abi, bytecode, deployed_bytecode })
640 }
641}