@@ -32,24 +32,34 @@ impl PostProcess for SwanPurchasePostProcessor {
3232        // we will cast strings to Address here 
3333        use  alloy:: primitives:: Address ; 
3434
35-         // first, collect the buy lines 
36-         let  mut  collecting = false ; 
37-         let  mut  shopping_list_lines = Vec :: new ( ) ; 
38-         for  line in  input. lines ( )  { 
39-             if  line. contains ( self . start_marker )  { 
40-                 // if we see the shop_list start marker, we can start collecting lines 
41-                 collecting = true ; 
42-             }  else  if  line. contains ( self . end_marker )  { 
43-                 // if we see the buy list end marker, we can stop collecting lines 
44-                 break ; 
45-             }  else  if  collecting { 
46-                 // if we are collecting, this must be a buy line 
47-                 shopping_list_lines. push ( line) ; 
48-             } 
49-         } 
35+         // get region of interest, that is between <shop_list> and </shop_list> 
36+         // with the markers excluded 
37+         let  roi = input
38+             . find ( self . start_marker ) 
39+             . map ( |start| start + self . start_marker . len ( ) ) 
40+             . and_then ( |start| { 
41+                 input[ start..] 
42+                     . find ( self . end_marker ) 
43+                     . map ( |end| input[ start..start + end] . to_string ( ) ) 
44+             } ) 
45+             . ok_or_else ( || { 
46+                 eyre:: eyre!( "could not find {} ~ {}" ,  self . start_marker,  self . end_marker) 
47+             } ) ?; 
48+ 
49+         // collect the chosen addresses 
50+         let  shopping_list:  Vec < & str >  = if  let  Ok ( list)  = serde_json:: from_str ( & roi)  { 
51+             // (1) try parsing the addresses from the input 
52+             list
53+         }  else  { 
54+             // (2) try splitting the input by lines and trimming all of them & removing empty lines 
55+             roi. lines ( ) 
56+                 . map ( |line| line. trim ( ) ) 
57+                 . filter ( |s| !s. is_empty ( ) ) 
58+                 . collect ( ) 
59+         } ; 
5060
5161        // then, do post processing on them to cast them to `Address` 
52-         let  addresses = shopping_list_lines 
62+         let  addresses = shopping_list 
5363            . into_iter ( ) 
5464            . filter_map ( |line| match  Address :: from_str ( line)  { 
5565                Ok ( address)  => Some ( address) , 
@@ -79,7 +89,7 @@ mod tests {
7989    use  super :: * ; 
8090
8191    #[ test]  
82-     fn  test_swan_post_processor_encoding ( )  { 
92+     fn  test_swan_post_processor_encoding_custom_addresses ( )  { 
8393        const  INPUT :  & str  = r#" 
8494some blabla here and there 
8595
@@ -118,14 +128,15 @@ some more blabla here
118128    } 
119129
120130    #[ test]  
121-     fn  test_swan_post_processor_encoding_2 ( )  { 
131+     fn  test_swan_post_processor_encoding_random_addresses ( )  { 
122132        const  INPUT :  & str  = r#" 
123133<shop_list> 
1241340x36f55f830D6E628a78Fcb70F73f9D005BaF88eE3 
125- 0xAd75C9358799e830F0c23a4BB28dF4D2cCCc8846 
126- 0x26F5B12b67D5F006826824A73F58b88D6bdAA74B 
127- 0x671527de058BaD60C6151cA29d501C87439bCF62 
128- 0x66FC9dC1De3db773891753CD257359A26e876305 
135+    0xAd75C9358799e830F0c23a4BB28dF4D2cCCc8846 
136+ 0x26F5B12b67D5F006826824A73F58b88D6bdAA74B    
137+    0x671527de058BaD60C6151cA29d501C87439bCF62 
138+ 
139+    0x66FC9dC1De3db773891753CD257359A26e876305 
129140</shop_list> 
130141"# ; 
131142
@@ -140,7 +151,29 @@ some more blabla here
140151            address!( "671527de058BaD60C6151cA29d501C87439bCF62" ) , 
141152            address!( "66FC9dC1De3db773891753CD257359A26e876305" ) , 
142153        ] ; 
143-         assert_eq ! ( addresses,  expected_addresses,  "must have listed addresses" ) ; 
154+         assert_eq ! ( addresses,  expected_addresses) ; 
155+     } 
156+ 
157+     #[ test]  
158+     fn  test_swan_post_processor_encoding_json_addresses ( )  { 
159+         // we are able to parse no matter how broken the JSON formatting is! 
160+         const  INPUT :  & str  = r#" 
161+ <shop_list> 
162+     ["0x36f55f830D6E628a78Fcb70F73f9D005BaF88eE3", 
163+     "0xAd75C9358799e830F0c23a4BB28dF4D2cCCc8846" 
164+     ]   
165+ </shop_list> 
166+ "# ; 
167+ 
168+         let  post_processor = SwanPurchasePostProcessor :: new ( "<shop_list>" ,  "</shop_list>" ) ; 
169+ 
170+         let  ( output,  _,  _)  = post_processor. post_process ( INPUT . to_string ( ) ) . unwrap ( ) ; 
171+         let  addresses = <Vec < Address > >:: abi_decode ( & output,  true ) . unwrap ( ) ; 
172+         let  expected_addresses = vec ! [ 
173+             address!( "36f55f830D6E628a78Fcb70F73f9D005BaF88eE3" ) , 
174+             address!( "Ad75C9358799e830F0c23a4BB28dF4D2cCCc8846" ) , 
175+         ] ; 
176+         assert_eq ! ( addresses,  expected_addresses) ; 
144177    } 
145178
146179    #[ test]  
@@ -156,11 +189,12 @@ im not even an address lol
156189"# ; 
157190
158191        let  post_processor = SwanPurchasePostProcessor :: new ( "<shop_list>" ,  "</shop_list>" ) ; 
159- 
160-         let  ( output,  _,  _)  = post_processor. post_process ( INPUT . to_string ( ) ) . unwrap ( ) ; 
161-         let  addresses = <Vec < Address > >:: abi_decode ( & output,  true ) . unwrap ( ) ; 
162-         let  expected_addresses = vec ! [ address!( "26F5B12b67D5F006826824A73F58b88D6bdAA74B" ) ] ; 
163-         assert_eq ! ( addresses,  expected_addresses,  "must have listed addresses" ) ; 
192+         let  output = post_processor. post_process ( INPUT . to_string ( ) ) . unwrap ( ) . 0 ; 
193+         assert_eq ! ( 
194+             <Vec <Address >>:: abi_decode( & output,  true ) . unwrap( ) , 
195+             vec![ address!( "26F5B12b67D5F006826824A73F58b88D6bdAA74B" ) ] , 
196+             "must have listed addresses" 
197+         ) ; 
164198    } 
165199
166200    #[ tokio:: test]  
0 commit comments