11use std:: {
22 fs,
3+ io:: Write ,
34 path:: PathBuf ,
45 process:: { exit, Command , ExitStatus , Stdio } ,
56 str:: FromStr ,
@@ -12,7 +13,7 @@ use espflash::{
1213 board_info, connect, flash_elf_image, monitor:: monitor, save_elf_as_image, ConnectOpts ,
1314 FlashConfigOpts , FlashOpts ,
1415 } ,
15- Chip , Config , ImageFormatId ,
16+ Chip , Config , ImageFormatId , InvalidPartitionTable , PartitionTable ,
1617} ;
1718use miette:: { IntoDiagnostic , Result , WrapErr } ;
1819
@@ -56,6 +57,8 @@ pub enum SubCommand {
5657 BoardInfo ( ConnectOpts ) ,
5758 /// Save the image to disk instead of flashing to device
5859 SaveImage ( SaveImageOpts ) ,
60+ /// Operations for partitions tables
61+ PartitionTable ( PartitionTableOpts ) ,
5962}
6063
6164#[ derive( Parser ) ]
@@ -102,6 +105,24 @@ pub struct SaveImageOpts {
102105 pub partition_table : Option < PathBuf > ,
103106}
104107
108+ #[ derive( Parser ) ]
109+ pub struct PartitionTableOpts {
110+ /// Convert CSV parition table to binary representation
111+ #[ clap( long, required_unless_present_any = [ "info" , "to-csv" ] ) ]
112+ to_binary : bool ,
113+ /// Convert binary partition table to CSV representation
114+ #[ clap( long, required_unless_present_any = [ "info" , "to-binary" ] ) ]
115+ to_csv : bool ,
116+ /// Show information on partition table
117+ #[ clap( short, long, required_unless_present_any = [ "to-binary" , "to-csv" ] ) ]
118+ info : bool ,
119+ /// Input partition table
120+ partition_table : PathBuf ,
121+ /// Optional output file name, if unset will output to stdout
122+ #[ clap( short, long) ]
123+ output : Option < PathBuf > ,
124+ }
125+
105126fn main ( ) -> Result < ( ) > {
106127 miette:: set_panic_hook ( ) ;
107128
@@ -117,6 +138,7 @@ fn main() -> Result<()> {
117138 match subcommand {
118139 BoardInfo ( opts) => board_info ( opts, config) ,
119140 SaveImage ( opts) => save_image ( opts, metadata, cargo_config) ,
141+ PartitionTable ( opts) => partition_table ( opts) ,
120142 }
121143 } else {
122144 flash ( opts, config, metadata, cargo_config)
@@ -344,6 +366,53 @@ fn save_image(
344366 Ok ( ( ) )
345367}
346368
369+ fn partition_table ( opts : PartitionTableOpts ) -> Result < ( ) > {
370+ if opts. to_binary {
371+ let input = fs:: read ( & opts. partition_table ) . into_diagnostic ( ) ?;
372+ let part_table = PartitionTable :: try_from_str ( String :: from_utf8 ( input) . into_diagnostic ( ) ?)
373+ . into_diagnostic ( ) ?;
374+
375+ // Use either stdout or a file if provided for the output.
376+ let mut writer: Box < dyn Write > = if let Some ( output) = opts. output {
377+ Box :: new ( fs:: File :: create ( output) . into_diagnostic ( ) ?)
378+ } else {
379+ Box :: new ( std:: io:: stdout ( ) )
380+ } ;
381+ part_table. save_bin ( & mut writer) . into_diagnostic ( ) ?;
382+ } else if opts. to_csv {
383+ let input = fs:: read ( & opts. partition_table ) . into_diagnostic ( ) ?;
384+ let part_table = PartitionTable :: try_from_bytes ( input) . into_diagnostic ( ) ?;
385+
386+ // Use either stdout or a file if provided for the output.
387+ let mut writer: Box < dyn Write > = if let Some ( output) = opts. output {
388+ Box :: new ( fs:: File :: create ( output) . into_diagnostic ( ) ?)
389+ } else {
390+ Box :: new ( std:: io:: stdout ( ) )
391+ } ;
392+ part_table. save_csv ( & mut writer) . into_diagnostic ( ) ?;
393+ } else if opts. info {
394+ let input = fs:: read ( & opts. partition_table ) . into_diagnostic ( ) ?;
395+
396+ // Try getting the partition table from either the csv or the binary representation and
397+ // fail otherwise.
398+ let part_table = if let Ok ( part_table) =
399+ PartitionTable :: try_from_bytes ( input. clone ( ) ) . into_diagnostic ( )
400+ {
401+ part_table
402+ } else if let Ok ( part_table) =
403+ PartitionTable :: try_from_str ( String :: from_utf8 ( input) . into_diagnostic ( ) ?)
404+ {
405+ part_table
406+ } else {
407+ return Err ( ( InvalidPartitionTable { } ) . into ( ) ) ;
408+ } ;
409+
410+ part_table. pretty_print ( ) ;
411+ }
412+
413+ Ok ( ( ) )
414+ }
415+
347416#[ cfg( unix) ]
348417fn exit_with_process_status ( status : ExitStatus ) -> ! {
349418 use std:: os:: unix:: process:: ExitStatusExt ;
0 commit comments