@@ -6,20 +6,20 @@ use crate::{
6
6
RustEnumVariantShared , RustField , RustItem , RustStruct , RustType , RustTypeAlias ,
7
7
RustTypeParseError ,
8
8
} ,
9
+ target_os_check:: accept_target_os,
9
10
visitors:: { ImportedType , TypeShareVisitor } ,
10
11
} ;
11
12
use itertools:: Either ;
12
- use log:: { debug, error , log_enabled } ;
13
+ use log:: debug;
13
14
use proc_macro2:: Ident ;
14
- use quote:: ToTokens ;
15
15
use std:: {
16
16
collections:: { BTreeSet , HashMap , HashSet } ,
17
17
convert:: TryFrom ,
18
18
path:: PathBuf ,
19
19
} ;
20
20
use syn:: {
21
21
ext:: IdentExt , parse:: ParseBuffer , punctuated:: Punctuated , visit:: Visit , Attribute , Expr ,
22
- ExprLit , Fields , GenericParam , ItemEnum , ItemStruct , ItemType , Lit , LitStr , Meta , MetaList ,
22
+ ExprLit , Fields , GenericParam , ItemEnum , ItemStruct , ItemType , LitStr , Meta , MetaList ,
23
23
MetaNameValue , Token ,
24
24
} ;
25
25
use thiserror:: Error ;
@@ -540,7 +540,7 @@ pub(crate) fn get_name_value_meta_items<'a>(
540
540
541
541
/// Returns all arguments passed into `#[{ident}(...)]` where `{ident}` can be `serde` or `typeshare` attributes
542
542
#[ inline( always) ]
543
- fn get_meta_items ( attr : & syn:: Attribute , ident : & str ) -> impl Iterator < Item = Meta > {
543
+ pub ( crate ) fn get_meta_items ( attr : & syn:: Attribute , ident : & str ) -> impl Iterator < Item = Meta > {
544
544
if attr. path ( ) . is_ident ( ident) {
545
545
Either :: Left (
546
546
attr. parse_args_with ( Punctuated :: < Meta , Token ! [ , ] > :: parse_terminated)
@@ -611,21 +611,7 @@ fn is_skipped(attrs: &[syn::Attribute], target_os: &[String]) -> bool {
611
611
. any ( |arg| matches ! ( arg, Meta :: Path ( path) if path. is_ident( "skip" ) ) )
612
612
} ) ;
613
613
614
- let target_rejected = || {
615
- !target_os. is_empty ( )
616
- && target_os
617
- . iter ( )
618
- . any ( |target| attrs. iter ( ) . any ( |attr| target_os_reject ( attr, target) ) )
619
- } ;
620
-
621
- let target_accepted = || {
622
- target_os. is_empty ( )
623
- || target_os
624
- . iter ( )
625
- . any ( |target| attrs. iter ( ) . all ( |attr| target_os_accept ( attr, target) ) )
626
- } ;
627
-
628
- typeshare_skip || target_rejected ( ) || !target_accepted ( )
614
+ typeshare_skip || !accept_target_os ( attrs, target_os)
629
615
}
630
616
631
617
// `#[typeshare(redacted)]`
@@ -636,127 +622,6 @@ fn is_redacted(attrs: &[syn::Attribute]) -> bool {
636
622
} )
637
623
}
638
624
639
- /// Check if this attribute rejects our optional `target_os` arguments.
640
- ///
641
- /// Examples:
642
- /// - `#[cfg(not(target_os = "windows"))]`
643
- /// - `#[cfg(not(any(target_os = "windows", target_os = "macos", feature = "my-feature")))]`
644
- /// - `#[cfg(not(all(target_os = "windows", feature = "my-feature")))]`
645
- #[ inline]
646
- pub ( crate ) fn target_os_reject ( attr : & Attribute , target_os : & str ) -> bool {
647
- if log_enabled ! ( log:: Level :: Debug ) {
648
- debug ! (
649
- "\t checking attribute {} for {target_os} reject" ,
650
- attr. into_token_stream( )
651
- ) ;
652
- }
653
-
654
- let reject = get_meta_items ( attr, "cfg" ) . any ( |meta| match & meta {
655
- // Check for "not"
656
- Meta :: List ( meta_list) if meta_list. path . is_ident ( "not" ) => {
657
- debug ! ( "\t \t parsing not" ) ;
658
- target_os_parse_not ( meta_list, target_os)
659
- }
660
- // If this attribute is not a target_os we accept
661
- _ => false ,
662
- } ) ;
663
- debug ! ( "\t \t reject {reject}" ) ;
664
- reject
665
- }
666
-
667
- /// Check if this attribute can accept our optional `target_os` arguments.
668
- ///
669
- /// Examples:
670
- /// - `#[cfg(target_os = "windows")]`
671
- /// - `#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]`
672
- /// - `#[cfg(all(target_os = "windows", feature = "my-feature"))]`
673
- #[ inline]
674
- pub ( crate ) fn target_os_accept ( attr : & Attribute , target_os : & str ) -> bool {
675
- if log_enabled ! ( log:: Level :: Debug ) {
676
- debug ! (
677
- "\t checking attribute {} for {target_os} accept" ,
678
- attr. into_token_stream( )
679
- ) ;
680
- }
681
-
682
- let accept = get_meta_items ( attr, "cfg" ) . all ( |meta| match & meta {
683
- // a single #[cfg(target_os = "target")]
684
- Meta :: NameValue ( MetaNameValue {
685
- path,
686
- value : Expr :: Lit ( ExprLit {
687
- lit : Lit :: Str ( v) , ..
688
- } ) ,
689
- ..
690
- } ) if path. is_ident ( "target_os" ) => v. value ( ) == target_os,
691
- // Combined with any or all
692
- // Ex: #[cfg(any(target_os = "target", feature = "test"))]
693
- Meta :: List ( meta_list)
694
- if meta_list. path . is_ident ( "any" ) || meta_list. path . is_ident ( "all" ) =>
695
- {
696
- argument_values ( "target_os" , meta_list) . any ( |t| t == target_os)
697
- }
698
- // If this attribute is not a target_os we accept
699
- _ => true ,
700
- } ) ;
701
- debug ! ( "\t \t accept {accept}" ) ;
702
- accept
703
- }
704
-
705
- /// Here we have a `#[cfg(not(..))]` attribute. There can be an `any` or `all` as well. We'll
706
- /// take any `target_os` and see if it matches the target_os parameter.
707
- #[ inline]
708
- fn target_os_parse_not ( list : & MetaList , target_os : & str ) -> bool {
709
- // Try to parse "any" or "all".
710
- let nested_meta_list =
711
- list. parse_args_with ( Punctuated :: < MetaList , Token ! [ , ] > :: parse_terminated) ;
712
-
713
- match nested_meta_list {
714
- Ok ( punctuated_meta) => punctuated_meta. iter ( ) . any ( |meta| {
715
- if log_enabled ! ( log:: Level :: Debug ) {
716
- if let Some ( ident) = meta. path . get_ident ( ) {
717
- debug ! ( "condition: {ident}" ) ;
718
- }
719
- }
720
-
721
- // The "all" here is treated as any. The assumption is there
722
- // will be one "target_os" combined with "feature" or some other
723
- // attribute that is not another "target_os".
724
- ( meta. path . is_ident ( "any" ) || meta. path . is_ident ( "all" ) )
725
- && argument_values ( "target_os" , meta) . any ( |target| target == target_os)
726
- } ) ,
727
- Err ( _err) => {
728
- debug ! ( "Parsing MetaNameValue" ) ;
729
- // "not" is not combined with "any" or "all".
730
- argument_values ( "target_os" , list) . any ( |target| target == target_os)
731
- }
732
- }
733
- }
734
-
735
- /// Yields all values for a given `arg_name`.
736
- #[ inline]
737
- fn argument_values < ' a > ( arg_name : & ' a str , list : & ' a MetaList ) -> impl Iterator < Item = String > + ' a {
738
- let name_values =
739
- list. parse_args_with ( Punctuated :: < MetaNameValue , Token ! [ , ] > :: parse_terminated) ;
740
-
741
- match name_values {
742
- Ok ( nvps) => Either :: Left ( nvps. into_iter ( ) . filter_map ( |nvp| {
743
- nvp. path
744
- . is_ident ( arg_name)
745
- . then_some ( & nvp. value )
746
- . and_then ( |value| match value {
747
- Expr :: Lit ( ExprLit {
748
- lit : Lit :: Str ( val) , ..
749
- } ) => Some ( val. value ( ) ) ,
750
- _ => None ,
751
- } )
752
- } ) ) ,
753
- Err ( err) => {
754
- error ! ( "Failed to parse meta list for {arg_name}: {err}" ) ;
755
- Either :: Right ( std:: iter:: empty ( ) )
756
- }
757
- }
758
- }
759
-
760
625
fn serde_attr ( attrs : & [ syn:: Attribute ] , ident : & str ) -> bool {
761
626
attrs. iter ( ) . any ( |attr| {
762
627
get_meta_items ( attr, SERDE )
0 commit comments