@@ -12,14 +12,23 @@ use proc_macro2::{Ident, Span, TokenStream};
1212use quote:: { quote, ToTokens } ;
1313use tinyjson:: JsonValue ;
1414
15- pub fn build ( path : impl AsRef < str > ) -> Result < ( ) , BuildError > {
16- write ( & parse_content ( & read_file ( path) ?) ?)
15+ #[ derive( Default ) ]
16+ pub struct Config {
17+ /// List of field names to give a private visibility modifier.
18+ ///
19+ /// This currently does not do any object traversal. If this list contains a value "foo", then
20+ /// any field named "foo", regardless of the depth in the JSON object, will be set to private.
21+ pub private_fields : Vec < String > ,
1722}
1823
19- pub fn build_merge ( paths : & [ impl AsRef < str > ] ) -> Result < ( ) , BuildError > {
24+ pub fn build ( path : impl AsRef < str > , opts : Config ) -> Result < ( ) , BuildError > {
25+ write ( & parse_content ( & read_file ( path) ?) ?, opts)
26+ }
27+
28+ pub fn build_merge ( paths : & [ impl AsRef < str > ] , opts : Config ) -> Result < ( ) , BuildError > {
2029 let map = parse_content_merge ( paths. iter ( ) . map ( read_file) . collect :: < Result < Vec < _ > , _ > > ( ) ?) ?;
2130
22- write ( & map)
31+ write ( & map, opts )
2332}
2433
2534fn read_file ( path : impl AsRef < str > ) -> Result < String , BuildError > {
@@ -76,9 +85,9 @@ fn parse_content_merge(contents: Vec<String>) -> Result<HashMap<String, JsonValu
7685 Ok ( map)
7786}
7887
79- fn write ( map : & HashMap < String , JsonValue > ) -> Result < ( ) , BuildError > {
88+ fn write ( map : & HashMap < String , JsonValue > , opts : Config ) -> Result < ( ) , BuildError > {
8089 let tokens = DesignTokens :: from_map ( map) ?;
81- let code = generate ( & tokens) ;
90+ let code = generate ( & tokens, opts ) ;
8291
8392 let output = Path :: new ( & std:: env:: var ( "OUT_DIR" ) ?) . join ( "design_tokens.rs" ) ;
8493
@@ -312,24 +321,25 @@ fn convert_number(n: &str) -> Result<JsonValue, BuildError> {
312321 Err ( BuildError :: Parse ( Error :: ExpectedNumber ) )
313322}
314323
315- fn generate ( tokens : & DesignTokens ) -> TokenStream {
316- Generator :: new ( tokens) . generate ( )
324+ fn generate ( tokens : & DesignTokens , opts : Config ) -> TokenStream {
325+ Generator :: new ( tokens, opts ) . generate ( )
317326}
318327
319328struct Generator {
320329 root : Group ,
330+ opts : Config ,
321331}
322332
323333impl Generator {
324- fn new ( tokens : & DesignTokens ) -> Self {
334+ fn new ( tokens : & DesignTokens , opts : Config ) -> Self {
325335 let root = Group {
326336 items : tokens. items . clone ( ) ,
327337 description : Some ( "Root-level Design Tokens type" . to_owned ( ) ) ,
328338 default_type : None ,
329339 extensions : HashMap :: new ( ) ,
330340 } ;
331341
332- Self { root }
342+ Self { root, opts }
333343 }
334344
335345 fn generate ( & self ) -> TokenStream {
@@ -410,13 +420,20 @@ impl Generator {
410420 nested. push ( group) ;
411421 }
412422
423+ let mut visibilities = vec ! [ ] ;
413424 let mut fields = vec ! [ ] ;
414425 let mut types = vec ! [ ] ;
415426 let mut descs = vec ! [ ] ;
416427 for ( name, token_or_group) in & items {
417428 let ( field, kind) = self . struct_field ( name, token_or_group) ;
418429 let desc = token_or_group. description ( ) . unwrap_or_default ( ) ;
430+ let visibility = if self . opts . private_fields . contains ( name) {
431+ quote ! { }
432+ } else {
433+ quote ! { pub }
434+ } ;
419435
436+ visibilities. push ( visibility) ;
420437 fields. push ( field) ;
421438 types. push ( kind) ;
422439 descs. push ( if desc. is_empty ( ) {
@@ -445,7 +462,7 @@ impl Generator {
445462 pub struct #group_name {
446463 #(
447464 #descs
448- pub #fields: #types,
465+ #visibilities #fields: #types,
449466 ) *
450467 }
451468
@@ -599,8 +616,7 @@ fn rustfmt(path: &Path) -> Result<(), BuildError> {
599616
600617 Command :: new ( std:: env:: var ( "RUSTFMT" ) . unwrap_or_else ( |_| "rustfmt" . to_string ( ) ) )
601618 . args ( [ "--emit" , "files" ] )
602- // .args(["--config", "format_strings=true,edition=2024,struct_lit_width=0,struct_lit_single_line=false,struct_variant_width=false"])
603- . args ( [ "--config" , "format_strings=true" ] )
619+ . args ( [ "--config" , "format_strings=true,max_width=120" ] )
604620 . arg ( path)
605621 . output ( )
606622 . map_err ( BuildError :: Fmt ) ?;
@@ -645,7 +661,7 @@ mod tests {
645661 let map: HashMap < String , JsonValue > = parse_content ( case) . unwrap ( ) ;
646662 let tokens = DesignTokens :: from_map ( & map) . unwrap ( ) ;
647663
648- let tokens = generate ( & tokens) ;
664+ let tokens = generate ( & tokens, Config :: default ( ) ) ;
649665 let abstract_file: File =
650666 syn:: parse2 ( tokens. clone ( ) ) . unwrap_or_else ( |err| panic ! ( "{err}:\n \n {tokens}" ) ) ;
651667 let code = prettyplease:: unparse ( & abstract_file) ;
@@ -672,7 +688,7 @@ mod tests {
672688 let map: HashMap < String , JsonValue > = parse_content ( case) . unwrap ( ) ;
673689 let tokens = DesignTokens :: from_map ( & map) . unwrap ( ) ;
674690
675- let tokens = generate ( & tokens) ;
691+ let tokens = generate ( & tokens, Config :: default ( ) ) ;
676692 let abstract_file: File =
677693 syn:: parse2 ( tokens. clone ( ) ) . unwrap_or_else ( |err| panic ! ( "{err}:\n \n {tokens}" ) ) ;
678694 let code = prettyplease:: unparse ( & abstract_file) ;
@@ -702,7 +718,7 @@ mod tests {
702718 let map: HashMap < String , JsonValue > = parse_content ( case) . unwrap ( ) ;
703719 let tokens = DesignTokens :: from_map ( & map) . unwrap ( ) ;
704720
705- let tokens = generate ( & tokens) ;
721+ let tokens = generate ( & tokens, Config :: default ( ) ) ;
706722 let abstract_file: File =
707723 syn:: parse2 ( tokens. clone ( ) ) . unwrap_or_else ( |err| panic ! ( "{err}:\n \n {tokens}" ) ) ;
708724 let code = prettyplease:: unparse ( & abstract_file) ;
@@ -733,7 +749,7 @@ mod tests {
733749 let map: HashMap < String , JsonValue > = parse_content ( case) . unwrap ( ) ;
734750 let tokens = DesignTokens :: from_map ( & map) . unwrap ( ) ;
735751
736- let tokens = generate ( & tokens) ;
752+ let tokens = generate ( & tokens, Config :: default ( ) ) ;
737753 let abstract_file: File =
738754 syn:: parse2 ( tokens. clone ( ) ) . unwrap_or_else ( |err| panic ! ( "{err}:\n \n {tokens}" ) ) ;
739755 let code = prettyplease:: unparse ( & abstract_file) ;
@@ -784,11 +800,44 @@ mod tests {
784800 let map = parse_content_merge ( contents. iter ( ) . map ( ToString :: to_string) . collect ( ) ) . unwrap ( ) ;
785801 let tokens = DesignTokens :: from_map ( & map) . unwrap ( ) ;
786802
787- let tokens = generate ( & tokens) ;
803+ let tokens = generate ( & tokens, Config :: default ( ) ) ;
788804 let abstract_file: File =
789805 syn:: parse2 ( tokens. clone ( ) ) . unwrap_or_else ( |err| panic ! ( "{err}:\n \n {tokens}" ) ) ;
790806 let code = prettyplease:: unparse ( & abstract_file) ;
791807
792808 insta:: assert_snapshot!( "merged content" , code. to_string( ) ) ;
793809 }
810+
811+ #[ cfg( any(
812+ not( any( feature = "ason" , feature = "toml" , feature = "jsonc" ) ) ,
813+ all( feature = "ason" , feature = "toml" , feature = "jsonc" )
814+ ) ) ]
815+ #[ test]
816+ fn test_private_fields ( ) {
817+ let content = indoc ! { r#"
818+ {
819+ "group name": {
820+ "token name": {
821+ "$value": 1234,
822+ "$type": "number"
823+ }
824+ },
825+ "alias name": {
826+ "$value": "{group name.token name}"
827+ }
828+ }
829+ "# } ;
830+
831+ let map = parse_content ( content) . unwrap ( ) ;
832+ let tokens = DesignTokens :: from_map ( & map) . unwrap ( ) ;
833+ let opts = Config {
834+ private_fields : vec ! [ "group name" . to_owned( ) ] ,
835+ } ;
836+ let tokens = generate ( & tokens, opts) ;
837+ let abstract_file: File =
838+ syn:: parse2 ( tokens. clone ( ) ) . unwrap_or_else ( |err| panic ! ( "{err}:\n \n {tokens}" ) ) ;
839+ let code = prettyplease:: unparse ( & abstract_file) ;
840+
841+ insta:: assert_snapshot!( "private fields" , code) ;
842+ }
794843}
0 commit comments