Skip to content

Commit 5de7086

Browse files
authored
fix(solc): use correct empty output selection (gakonst#1185)
1 parent 82d5741 commit 5de7086

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

ethers-solc/src/artifacts/output_selection.rs

+43-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! bindings for standard json output selection
22
3-
use serde::{Deserialize, Deserializer, Serialize, Serializer};
3+
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
44
use std::{collections::BTreeMap, fmt, str::FromStr};
55

66
/// Represents the desired outputs based on a File `(file -> (contract -> [outputs]))`
@@ -68,7 +68,7 @@ pub type FileOutputSelection = BTreeMap<String, Vec<String>>;
6868
/// }
6969
/// }
7070
/// ```
71-
#[derive(Debug, Clone, Eq, PartialEq, Default, Serialize, Deserialize)]
71+
#[derive(Debug, Clone, Eq, PartialEq, Default, Deserialize)]
7272
#[serde(transparent)]
7373
pub struct OutputSelection(pub BTreeMap<String, FileOutputSelection>);
7474

@@ -121,6 +121,39 @@ impl OutputSelection {
121121
}
122122
}
123123

124+
// this will make sure that if the `FileOutputSelection` for a certain file is empty will be
125+
// serializes as `"*" : []` because
126+
// > Contract level (needs the contract name or "*") <https://docs.soliditylang.org/en/v0.8.13/using-the-compiler.html>
127+
impl Serialize for OutputSelection {
128+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
129+
where
130+
S: Serializer,
131+
{
132+
struct EmptyFileOutput;
133+
134+
impl Serialize for EmptyFileOutput {
135+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136+
where
137+
S: Serializer,
138+
{
139+
let mut map = serializer.serialize_map(Some(1))?;
140+
map.serialize_entry("*", &[] as &[String])?;
141+
map.end()
142+
}
143+
}
144+
145+
let mut map = serializer.serialize_map(Some(self.0.len()))?;
146+
for (file, selection) in self.0.iter() {
147+
if selection.is_empty() {
148+
map.serialize_entry(file, &EmptyFileOutput {})?;
149+
} else {
150+
map.serialize_entry(file, selection)?;
151+
}
152+
}
153+
map.end()
154+
}
155+
}
156+
124157
impl AsRef<BTreeMap<String, FileOutputSelection>> for OutputSelection {
125158
fn as_ref(&self) -> &BTreeMap<String, FileOutputSelection> {
126159
&self.0
@@ -532,4 +565,12 @@ mod tests {
532565

533566
assert_eq!(json, serde_json::to_string(&deserde_selection).unwrap());
534567
}
568+
569+
#[test]
570+
fn empty_outputselection_serde_works() {
571+
let mut empty = OutputSelection::default();
572+
empty.0.insert("contract.sol".to_string(), OutputSelection::empty_file_output_select());
573+
let s = serde_json::to_string(&empty).unwrap();
574+
assert_eq!(s, r#"{"contract.sol":{"*":[]}}"#);
575+
}
535576
}

0 commit comments

Comments
 (0)