ethcontract_common/artifact/
truffle.rs1use crate::artifact::Artifact;
14use crate::errors::ArtifactError;
15use crate::Contract;
16use serde_json::{from_reader, from_slice, from_str, from_value, to_string, Value};
17use std::fs::File;
18use std::io::{BufReader, Read};
19use std::path::Path;
20
21#[must_use = "truffle loaders do nothing unless you load them"]
23pub struct TruffleLoader {
24 pub origin: Option<String>,
28
29 pub name: Option<String>,
33}
34
35impl TruffleLoader {
36 pub fn new() -> Self {
38 TruffleLoader {
39 origin: None,
40 name: None,
41 }
42 }
43
44 pub fn with_origin(origin: impl Into<String>) -> Self {
46 TruffleLoader {
47 origin: Some(origin.into()),
48 name: None,
49 }
50 }
51
52 pub fn origin(mut self, origin: impl Into<String>) -> Self {
56 self.origin = Some(origin.into());
57 self
58 }
59
60 pub fn name(mut self, name: impl Into<String>) -> Self {
64 self.name = Some(name.into());
65 self
66 }
67
68 pub fn load_from_reader(&self, v: impl Read) -> Result<Artifact, ArtifactError> {
70 self.load_artifact("<unknown>", v, from_reader)
71 }
72
73 pub fn load_from_slice(&self, v: &[u8]) -> Result<Artifact, ArtifactError> {
75 self.load_artifact("<unknown>", v, from_slice)
76 }
77
78 pub fn load_from_str(&self, v: &str) -> Result<Artifact, ArtifactError> {
80 self.load_artifact("<unknown>", v, from_str)
81 }
82
83 pub fn load_from_value(&self, v: Value) -> Result<Artifact, ArtifactError> {
85 self.load_artifact("<unknown>", v, from_value)
86 }
87
88 pub fn load_from_file(&self, p: impl AsRef<Path>) -> Result<Artifact, ArtifactError> {
90 let path = p.as_ref();
91 let file = File::open(path)?;
92 let reader = BufReader::new(file);
93 self.load_artifact(path.display(), reader, from_reader)
94 }
95
96 pub fn load_contract_from_reader(&self, v: impl Read) -> Result<Contract, ArtifactError> {
98 self.load_contract(v, from_reader)
99 }
100
101 pub fn load_contract_from_slice(&self, v: &[u8]) -> Result<Contract, ArtifactError> {
103 self.load_contract(v, from_slice)
104 }
105
106 pub fn load_contract_from_str(&self, v: &str) -> Result<Contract, ArtifactError> {
108 self.load_contract(v, from_str)
109 }
110
111 pub fn load_contract_from_value(&self, v: Value) -> Result<Contract, ArtifactError> {
113 self.load_contract(v, from_value)
114 }
115
116 pub fn load_contract_from_file(&self, p: impl AsRef<Path>) -> Result<Contract, ArtifactError> {
118 let path = p.as_ref();
119 let file = File::open(path)?;
120 let reader = BufReader::new(file);
121 self.load_contract(reader, from_reader)
122 }
123
124 fn load_artifact<T>(
125 &self,
126 origin: impl ToString,
127 source: T,
128 loader: impl FnOnce(T) -> serde_json::Result<Contract>,
129 ) -> Result<Artifact, ArtifactError> {
130 let origin = self.origin.clone().unwrap_or_else(|| origin.to_string());
131 let mut artifact = Artifact::with_origin(origin);
132 artifact.insert(self.load_contract(source, loader)?);
133 Ok(artifact)
134 }
135
136 fn load_contract<T>(
137 &self,
138 source: T,
139 loader: impl FnOnce(T) -> serde_json::Result<Contract>,
140 ) -> Result<Contract, ArtifactError> {
141 let mut contract: Contract = loader(source)?;
142
143 if let Some(name) = &self.name {
144 contract.name.clone_from(name);
145 }
146
147 Ok(contract)
148 }
149
150 pub fn save_to_string(contract: &Contract) -> Result<String, ArtifactError> {
152 to_string(contract).map_err(Into::into)
153 }
154}
155
156impl Default for TruffleLoader {
157 fn default() -> Self {
158 TruffleLoader::new()
159 }
160}