1- use std:: borrow:: Cow ;
2-
3- use syn:: { GenericArgument , Path , PathArguments , Type , TypeArray , TypePath , parse_quote} ;
1+ use proc_macro2:: Span ;
2+ use syn:: {
3+ GenericArgument , Path , PathArguments , Type , TypeArray , TypePath , TypeReference ,
4+ parse_quote_spanned,
5+ } ;
46
57use crate :: Method ;
68
7- pub ( crate ) fn auto_deref ( ty : & Type , method : Method ) -> Option < Cow < ' _ , Type > > {
9+ pub ( crate ) fn auto_deref ( ty : & Type , method : Method , span : Span ) -> Option < ( Type , usize ) > {
10+ let mut ty = ty. clone ( ) ;
11+ let mut count = 0 ;
12+
13+ while let Some ( next_ty) = auto_deref_inner ( & ty, method, span) {
14+ ty = next_ty;
15+ count += 1 ;
16+ }
17+
18+ if count > 0 { Some ( ( ty, count) ) } else { None }
19+ }
20+
21+ pub ( crate ) fn auto_deref_inner ( ty : & Type , method : Method , span : Span ) -> Option < Type > {
822 let segments = match ty {
23+ Type :: Reference ( TypeReference {
24+ mutability : Some ( _) ,
25+ elem,
26+ ..
27+ } ) => return Some ( * elem. clone ( ) ) ,
928 Type :: Path ( TypePath {
1029 path : Path { segments, .. } ,
1130 ..
1231 } ) => segments,
13- Type :: Array ( TypeArray { elem, .. } ) => return Some ( Cow :: Owned ( parse_quote ! ( [ #elem] ) ) ) ,
32+ Type :: Array ( TypeArray { elem, .. } ) => return Some ( parse_quote_spanned ! ( span => [ #elem] ) ) ,
1433 _ => {
1534 return None ;
1635 }
1736 } ;
1837
1938 let last_segment = segments. last ( ) ?;
2039 if last_segment. ident == "String" {
21- return Some ( Cow :: Owned ( parse_quote ! ( str ) ) ) ;
40+ return Some ( parse_quote_spanned ! ( span => str ) ) ;
2241 }
2342
2443 if last_segment. ident == "PathBuf" {
25- return Some ( Cow :: Owned ( parse_quote ! ( std:: path:: Path ) ) ) ;
44+ return Some ( parse_quote_spanned ! ( span => std:: path:: Path ) ) ;
2645 }
2746
2847 if last_segment. ident == "OsString" {
29- return Some ( Cow :: Owned ( parse_quote ! ( std:: ffi:: OsStr ) ) ) ;
48+ return Some ( parse_quote_spanned ! ( span => std:: ffi:: OsStr ) ) ;
3049 }
3150
3251 if last_segment. ident == "Vec" {
@@ -38,7 +57,7 @@ pub(crate) fn auto_deref(ty: &Type, method: Method) -> Option<Cow<'_, Type>> {
3857 return None ;
3958 } ;
4059
41- return Some ( Cow :: Owned ( parse_quote ! ( [ #inner_type] ) ) ) ;
60+ return Some ( parse_quote_spanned ! ( span => [ #inner_type] ) ) ;
4261 }
4362
4463 if last_segment. ident == "Box" {
@@ -50,7 +69,7 @@ pub(crate) fn auto_deref(ty: &Type, method: Method) -> Option<Cow<'_, Type>> {
5069 return None ;
5170 } ;
5271
53- return Some ( Cow :: Borrowed ( inner_type) ) ;
72+ return Some ( inner_type. clone ( ) ) ;
5473 }
5574
5675 if method == Method :: Get {
@@ -63,7 +82,7 @@ pub(crate) fn auto_deref(ty: &Type, method: Method) -> Option<Cow<'_, Type>> {
6382 return None ;
6483 } ;
6584
66- return Some ( Cow :: Borrowed ( inner_type) ) ;
85+ return Some ( inner_type. clone ( ) ) ;
6786 }
6887
6988 if last_segment. ident == "Cow" {
@@ -79,7 +98,7 @@ pub(crate) fn auto_deref(ty: &Type, method: Method) -> Option<Cow<'_, Type>> {
7998 return None ;
8099 } ;
81100
82- return Some ( Cow :: Borrowed ( t ) ) ;
101+ return Some ( t . clone ( ) ) ;
83102 }
84103 }
85104
0 commit comments