1
1
use crate :: { error:: SolcError , Result } ;
2
2
use serde:: { Deserialize , Serialize } ;
3
- use std:: fmt;
3
+ use std:: { fmt, str :: FromStr } ;
4
4
5
5
const DAPPTOOLS_CONTRACTS_DIR : & str = "src" ;
6
6
const JS_CONTRACTS_DIR : & str = "contracts" ;
@@ -42,6 +42,31 @@ pub struct Remapping {
42
42
pub path : String ,
43
43
}
44
44
45
+ #[ derive( thiserror:: Error , Debug , PartialEq , PartialOrd ) ]
46
+ pub enum RemappingError {
47
+ #[ error( "no prefix found" ) ]
48
+ NoPrefix ,
49
+ #[ error( "no target found" ) ]
50
+ NoTarget ,
51
+ }
52
+
53
+ impl FromStr for Remapping {
54
+ type Err = RemappingError ;
55
+
56
+ fn from_str ( remapping : & str ) -> std:: result:: Result < Self , Self :: Err > {
57
+ let mut split = remapping. split ( '=' ) ;
58
+ let name = split. next ( ) . ok_or_else ( || RemappingError :: NoPrefix ) ?. to_string ( ) ;
59
+ if name. is_empty ( ) {
60
+ return Err ( RemappingError :: NoPrefix )
61
+ }
62
+ let path = split. next ( ) . ok_or_else ( || RemappingError :: NoTarget ) ?. to_string ( ) ;
63
+ if path. is_empty ( ) {
64
+ return Err ( RemappingError :: NoTarget )
65
+ }
66
+ Ok ( Remapping { name, path } )
67
+ }
68
+ }
69
+
45
70
impl Serialize for Remapping {
46
71
fn serialize < S > ( & self , serializer : S ) -> std:: result:: Result < S :: Ok , S :: Error >
47
72
where
@@ -57,16 +82,7 @@ impl<'de> Deserialize<'de> for Remapping {
57
82
D : serde:: de:: Deserializer < ' de > ,
58
83
{
59
84
let remapping = String :: deserialize ( deserializer) ?;
60
- let mut split = remapping. split ( '=' ) ;
61
- let name = split
62
- . next ( )
63
- . ok_or_else ( || serde:: de:: Error :: custom ( "no remapping prefix found" ) ) ?
64
- . to_string ( ) ;
65
- let path = split
66
- . next ( )
67
- . ok_or_else ( || serde:: de:: Error :: custom ( "no remapping path found" ) ) ?
68
- . to_string ( ) ;
69
- Ok ( Remapping { name, path } )
85
+ Remapping :: from_str ( & remapping) . map_err ( |e| serde:: de:: Error :: custom ( e) )
70
86
}
71
87
}
72
88
@@ -163,6 +179,20 @@ impl Remapping {
163
179
mod tests {
164
180
use super :: * ;
165
181
182
+ #[ test]
183
+ fn serde ( ) {
184
+ let remapping = "oz=../b/c/d" ;
185
+ let remapping = Remapping :: from_str ( & remapping) . unwrap ( ) ;
186
+ assert_eq ! ( remapping. name, "oz" . to_string( ) ) ;
187
+ assert_eq ! ( remapping. path, "../b/c/d" . to_string( ) ) ;
188
+
189
+ let err = Remapping :: from_str ( "" ) . unwrap_err ( ) ;
190
+ assert_eq ! ( err, RemappingError :: NoPrefix ) ;
191
+
192
+ let err = Remapping :: from_str ( "oz=" ) . unwrap_err ( ) ;
193
+ assert_eq ! ( err, RemappingError :: NoTarget ) ;
194
+ }
195
+
166
196
// https://doc.rust-lang.org/rust-by-example/std_misc/fs.html
167
197
fn touch ( path : & std:: path:: Path ) -> std:: io:: Result < ( ) > {
168
198
match std:: fs:: OpenOptions :: new ( ) . create ( true ) . write ( true ) . open ( path) {
0 commit comments