@@ -11,7 +11,7 @@ use cambridge_asm::{
1111 parse:: { self , DefaultSet } ,
1212} ;
1313use clap:: { Parser , ValueEnum } ;
14- use std:: ffi :: OsString ;
14+ use std:: { fs :: File , io :: Read , path :: PathBuf } ;
1515
1616#[ derive( Parser ) ]
1717#[ clap( name = "Cambridge Pseudoassembly Interpreter" ) ]
@@ -22,7 +22,7 @@ enum Commands {
2222 /// Run compiled or plaintext pseudoassembly
2323 Run {
2424 /// Path to the input file containing compiled or plaintext pseudoassembly
25- path : OsString ,
25+ path : PathBuf ,
2626
2727 /// Increase logging level
2828 #[ arg( short = 'v' , long = "verbose" , action = clap:: ArgAction :: Count ) ]
@@ -41,11 +41,11 @@ enum Commands {
4141 /// Compile pseudoassembly
4242 Compile {
4343 /// Path to the input file containing pseudoassembly
44- input : OsString ,
44+ input : PathBuf ,
4545
4646 /// Path to output file
4747 #[ arg( short = 'o' , long = "output" ) ]
48- output : Option < OsString > ,
48+ output : Option < PathBuf > ,
4949
5050 /// Increase logging level
5151 #[ arg( short = 'v' , long = "verbose" , action = clap:: ArgAction :: Count ) ]
@@ -73,15 +73,15 @@ enum InFormats {
7373 Json ,
7474 Ron ,
7575 Yaml ,
76- Bin ,
76+ Cbor ,
7777}
7878
7979#[ derive( ValueEnum , Clone ) ]
8080enum OutFormats {
8181 Json ,
8282 Ron ,
8383 Yaml ,
84- Bin ,
84+ Cbor ,
8585}
8686
8787fn main ( ) -> anyhow:: Result < ( ) > {
@@ -113,34 +113,30 @@ fn main() -> anyhow::Result<()> {
113113}
114114
115115#[ allow( clippy:: enum_glob_use, clippy:: needless_pass_by_value) ]
116- fn run (
117- path : OsString ,
118- verbosity : u8 ,
119- bench : bool ,
120- format : InFormats ,
121- io : Io ,
122- ) -> anyhow:: Result < ( ) > {
116+ fn run ( path : PathBuf , verbosity : u8 , bench : bool , format : InFormats , io : Io ) -> anyhow:: Result < ( ) > {
123117 use InFormats :: * ;
124118
125119 init_logger ( verbosity) ;
126120
127- let prog_bytes = std :: fs :: read ( path) ?;
121+ let file = File :: open ( path) ?;
128122
129123 let mut timer = bench. then ( std:: time:: Instant :: now) ;
130124
125+ let read_to_string = |mut f : File | -> std:: io:: Result < _ > {
126+ #[ allow( clippy:: cast_possible_truncation) ]
127+ let mut buf = String :: with_capacity ( f. metadata ( ) ?. len ( ) as usize ) ;
128+ f. read_to_string ( & mut buf) ?;
129+ Ok ( buf)
130+ } ;
131+
131132 let mut executor = match format {
132- Pasm => parse:: jit :: < DefaultSet > ( String :: from_utf8_lossy ( & prog_bytes ) , io) . unwrap ( ) ,
133- Json => serde_json:: from_str :: < CompiledProg > ( & String :: from_utf8_lossy ( & prog_bytes ) ) ?
133+ Pasm => parse:: jit :: < DefaultSet > ( read_to_string ( file ) ? , io) . unwrap ( ) ,
134+ Json => serde_json:: from_str :: < CompiledProg > ( & read_to_string ( file ) ? ) ?
134135 . to_executor :: < DefaultSet > ( io) ,
135- Ron => ron:: from_str :: < CompiledProg > ( & String :: from_utf8_lossy ( & prog_bytes) ) ?
136+ Ron => ron:: from_str :: < CompiledProg > ( & read_to_string ( file) ?) ?. to_executor :: < DefaultSet > ( io) ,
137+ Yaml => serde_yaml:: from_str :: < CompiledProg > ( & read_to_string ( file) ?) ?
136138 . to_executor :: < DefaultSet > ( io) ,
137- Yaml => serde_yaml:: from_str :: < CompiledProg > ( & String :: from_utf8_lossy ( & prog_bytes) ) ?
138- . to_executor :: < DefaultSet > ( io) ,
139- Bin => {
140- bincode:: decode_from_slice :: < CompiledProg , _ > ( & prog_bytes, bincode:: config:: standard ( ) ) ?
141- . 0
142- . to_executor :: < DefaultSet > ( io)
143- }
139+ Cbor => ciborium:: from_reader :: < CompiledProg , _ > ( file) ?. to_executor :: < DefaultSet > ( io) ,
144140 } ;
145141
146142 timer = timer. map ( |t| {
@@ -163,13 +159,13 @@ fn run(
163159
164160#[ allow( clippy:: enum_glob_use, clippy:: needless_pass_by_value) ]
165161fn compile (
166- mut input : OsString ,
167- output : Option < OsString > ,
162+ mut input : PathBuf ,
163+ output : Option < PathBuf > ,
168164 verbosity : u8 ,
169165 format : OutFormats ,
170166 minify : bool ,
171167 debug : bool ,
172- ) -> std :: io :: Result < ( ) > {
168+ ) -> anyhow :: Result < ( ) > {
173169 use OutFormats :: * ;
174170
175171 init_logger ( verbosity) ;
@@ -179,45 +175,50 @@ fn compile(
179175 let compiled = compile:: compile :: < DefaultSet > ( prog, debug) . unwrap ( ) ;
180176
181177 let output_path = output. unwrap_or_else ( || {
182- input. push ( match format {
183- Json => ".json" ,
184- Ron => ".ron" ,
185- Yaml => ".yaml" ,
186- Bin => ".bin" ,
187- } ) ;
178+ let ext = match format {
179+ Json => "json" ,
180+ Ron => "ron" ,
181+ Yaml => "yaml" ,
182+ Cbor => "cbor" ,
183+ } ;
184+ input. set_extension ( ext) ;
188185 input
189186 } ) ;
190187
191- let serialised = match format {
192- Json => {
193- use serde_json:: ser:: { to_string, to_string_pretty} ;
194-
195- {
196- if minify {
197- to_string ( & compiled) . unwrap ( )
198- } else {
199- to_string_pretty ( & compiled) . unwrap ( )
200- }
201- }
202- . into_bytes ( )
188+ let file = std:: fs:: OpenOptions :: new ( )
189+ . create ( true )
190+ . truncate ( true )
191+ . write ( true )
192+ . open ( output_path) ?;
193+
194+ let json = |w : File , v : & CompiledProg | {
195+ if minify {
196+ serde_json:: to_writer ( w, v)
197+ } else {
198+ serde_json:: to_writer_pretty ( w, v)
203199 }
204- Ron => {
205- use ron:: ser:: { to_string, to_string_pretty, PrettyConfig } ;
206-
207- {
208- if minify {
209- to_string ( & compiled) . unwrap ( )
210- } else {
211- to_string_pretty ( & compiled, PrettyConfig :: default ( ) ) . unwrap ( )
212- }
213- }
214- . into_bytes ( )
200+ } ;
201+
202+ let ron = |w : File , v : & CompiledProg | {
203+ if minify {
204+ ron:: ser:: to_writer ( w, v)
205+ } else {
206+ ron:: ser:: to_writer_pretty ( w, v, ron:: ser:: PrettyConfig :: default ( ) )
215207 }
216- Yaml => serde_yaml:: to_string ( & compiled) . unwrap ( ) . into_bytes ( ) ,
217- Bin => bincode:: encode_to_vec ( & compiled, bincode:: config:: standard ( ) ) . unwrap ( ) ,
218208 } ;
219209
220- std:: fs:: write ( output_path, serialised)
210+ let yaml = |w : File , v : & CompiledProg | serde_yaml:: to_writer ( w, v) ;
211+
212+ let cbor = |w : File , v : & CompiledProg | ciborium:: ser:: into_writer ( v, w) ;
213+
214+ match format {
215+ Json => json ( file, & compiled) ?,
216+ Ron => ron ( file, & compiled) ?,
217+ Yaml => yaml ( file, & compiled) ?,
218+ Cbor => cbor ( file, & compiled) ?,
219+ } ;
220+
221+ Ok ( ( ) )
221222}
222223
223224fn init_logger ( verbosity : u8 ) {
0 commit comments