@@ -6,12 +6,12 @@ use clap::builder::PossibleValuesParser;
66use clap:: builder:: TypedValueParser as _;
77use clap:: { value_parser, Args , Command , Parser , ValueHint } ;
88use clap_complete:: { generate, Generator , Shell } ;
9+ use merge:: Merge ;
910use num_format:: CustomFormat ;
1011use onefetch_image:: ImageProtocol ;
1112use onefetch_manifest:: ManifestType ;
1213use regex:: Regex ;
13- use serde:: Serialize ;
14- use merge:: Merge ;
14+ use serde:: { de:: Visitor , Serializer , Deserialize , Serialize } ;
1515use std:: env;
1616use std:: io;
1717use std:: path:: PathBuf ;
@@ -21,17 +21,19 @@ use strum::IntoEnumIterator;
2121const COLOR_RESOLUTIONS : [ & str ; 5 ] = [ "16" , "32" , "64" , "128" , "256" ] ;
2222pub const NO_BOTS_DEFAULT_REGEX_PATTERN : & str = r"(?:-|\s)[Bb]ot$|\[[Bb]ot\]" ;
2323
24- #[ derive( Clone , Debug , Parser , PartialEq , Eq , Merge ) ]
24+ #[ derive( Clone , Debug , Parser , PartialEq , Eq , Merge , Serialize , Deserialize ) ]
2525#[ command( version, about) ]
2626pub struct CliOptions {
2727 /// Run as if onefetch was started in <input> instead of the current working directory
2828 #[ arg( default_value = "." , hide_default_value = true , value_hint = ValueHint :: DirPath ) ]
2929 #[ merge( skip) ]
30+ #[ serde( skip) ]
3031 pub input : PathBuf ,
3132 /// Specify a custom path to a config file.
3233 /// Default config is located at ${HOME}/.config/onefetch/config.conf.
3334 #[ arg( long, value_hint = ValueHint :: AnyPath ) ]
3435 #[ merge( skip) ]
36+ #[ serde( skip) ]
3537 pub config_path : Option < PathBuf > ,
3638 #[ command( flatten) ]
3739 pub info : InfoCliOptions ,
@@ -49,7 +51,7 @@ pub struct CliOptions {
4951 pub other : OtherCliOptions ,
5052}
5153
52- #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge ) ]
54+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge , Serialize , Deserialize ) ]
5355#[ command( next_help_heading = "INFO" ) ]
5456pub struct InfoCliOptions {
5557 /// Allows you to disable FIELD(s) from appearing in the output
@@ -132,7 +134,7 @@ pub struct InfoCliOptions {
132134 pub r#type : Vec < LanguageType > ,
133135}
134136
135- #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge ) ]
137+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge , Serialize , Deserialize ) ]
136138#[ command( next_help_heading = "ASCII" ) ]
137139pub struct AsciiCliOptions {
138140 /// Takes a non-empty STRING as input to replace the ASCII logo
@@ -164,6 +166,7 @@ pub struct AsciiCliOptions {
164166 hide_possible_values = true
165167 ) ]
166168 #[ merge( skip) ]
169+ #[ serde( skip) ]
167170 pub ascii_language : Option < Language > ,
168171 /// Specify when to use true color
169172 ///
@@ -173,7 +176,7 @@ pub struct AsciiCliOptions {
173176 pub true_color : When ,
174177}
175178
176- #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge ) ]
179+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge , Serialize , Deserialize ) ]
177180#[ command( next_help_heading = "IMAGE" ) ]
178181pub struct ImageCliOptions {
179182 /// Path to the IMAGE file
@@ -183,6 +186,7 @@ pub struct ImageCliOptions {
183186 /// Which image PROTOCOL to use
184187 #[ arg( long, value_enum, requires = "image" , value_name = "PROTOCOL" ) ]
185188 #[ merge( skip) ]
189+ #[ serde( skip) ]
186190 pub image_protocol : Option < ImageProtocol > ,
187191 /// VALUE of color resolution to use with SIXEL backend
188192 #[ arg(
@@ -197,7 +201,7 @@ pub struct ImageCliOptions {
197201 pub color_resolution : usize ,
198202}
199203
200- #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge ) ]
204+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Merge , Serialize , Deserialize ) ]
201205#[ command( next_help_heading = "TEXT FORMATTING" ) ]
202206pub struct TextForamttingCliOptions {
203207 /// Changes the text colors (X X X...)
@@ -229,7 +233,7 @@ pub struct TextForamttingCliOptions {
229233 #[ merge( strategy = merge:: bool :: overwrite_false) ]
230234 pub no_bold : bool ,
231235}
232- #[ derive( Clone , Debug , Args , PartialEq , Eq , Default , Merge ) ]
236+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Default , Merge , Serialize , Deserialize ) ]
233237#[ command( next_help_heading = "VISUALS" ) ]
234238pub struct VisualsCliOptions {
235239 /// Hides the color palette
@@ -248,29 +252,33 @@ pub struct VisualsCliOptions {
248252 pub nerd_fonts : bool ,
249253}
250254
251- #[ derive( Clone , Debug , Args , PartialEq , Eq , Default , Merge ) ]
255+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Default , Merge , Serialize , Deserialize ) ]
252256#[ command( next_help_heading = "DEVELOPER" ) ]
253257pub struct DeveloperCliOptions {
254258 /// Outputs Onefetch in a specific format
255259 #[ arg( long, short, value_name = "FORMAT" , value_enum) ]
256260 #[ merge( skip) ]
261+ #[ serde( skip) ]
257262 pub output : Option < SerializationFormat > ,
258263 /// If provided, outputs the completion file for given SHELL
259264 #[ arg( long = "generate" , value_name = "SHELL" , value_enum) ]
260265 #[ merge( skip) ]
266+ #[ serde( skip) ]
261267 pub completion : Option < Shell > ,
262268}
263269
264- #[ derive( Clone , Debug , Args , PartialEq , Eq , Default , Merge ) ]
270+ #[ derive( Clone , Debug , Args , PartialEq , Eq , Default , Merge , Serialize , Deserialize ) ]
265271#[ command( next_help_heading = "OTHER" ) ]
266272pub struct OtherCliOptions {
267273 /// Prints out supported languages
268274 #[ arg( long, short) ]
269275 #[ merge( skip) ]
276+ #[ serde( skip) ]
270277 pub languages : bool ,
271278 /// Prints out supported package managers
272279 #[ arg( long, short) ]
273280 #[ merge( skip) ]
281+ #[ serde( skip) ]
274282 pub package_managers : bool ,
275283}
276284
@@ -386,14 +394,14 @@ pub fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
386394 generate ( gen, cmd, cmd. get_name ( ) . to_string ( ) , & mut io:: stdout ( ) ) ;
387395}
388396
389- #[ derive( clap:: ValueEnum , Clone , PartialEq , Eq , Debug ) ]
397+ #[ derive( clap:: ValueEnum , Clone , PartialEq , Eq , Debug , Serialize , Deserialize ) ]
390398pub enum When {
391399 Auto ,
392400 Never ,
393401 Always ,
394402}
395403
396- #[ derive( clap:: ValueEnum , Clone , PartialEq , Eq , Debug , Serialize , Copy ) ]
404+ #[ derive( clap:: ValueEnum , Clone , PartialEq , Eq , Debug , Serialize , Deserialize , Copy ) ]
397405pub enum NumberSeparator {
398406 Plain ,
399407 Comma ,
@@ -512,3 +520,37 @@ impl FromStr for MyRegex {
512520 Ok ( MyRegex ( Regex :: new ( s) ?) )
513521 }
514522}
523+
524+ impl Serialize for MyRegex {
525+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
526+ where
527+ S : Serializer ,
528+ { serializer. serialize_str ( self . 0 . as_str ( ) ) }
529+ }
530+
531+ pub struct RegVisitor ;
532+
533+ impl < ' de > Visitor < ' de > for RegVisitor {
534+ type Value = MyRegex ;
535+
536+ fn expecting ( & self , formatter : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
537+ formatter. write_str ( "regex" )
538+ }
539+
540+ fn visit_str < E > ( self , v : & str ) -> Result < Self :: Value , E >
541+ where
542+ E : serde:: de:: Error , {
543+ match MyRegex :: from_str ( v) {
544+ Ok ( regex) => Ok ( regex) ,
545+ Err ( error) => Err ( serde:: de:: Error :: custom ( error) )
546+ }
547+ }
548+ }
549+
550+ impl < ' de > Deserialize < ' de > for MyRegex {
551+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
552+ where
553+ D : serde:: Deserializer < ' de > , {
554+ deserializer. deserialize_str ( RegVisitor )
555+ }
556+ }
0 commit comments