77use crate :: Error ;
88use regex:: Captures ;
99use std:: borrow:: Cow ;
10+ use std:: cell:: LazyCell ;
1011
11- fn get < ' s > ( c : & Captures < ' s > , group : usize ) -> Option < & ' s str > {
12- c. get ( group) . map ( |g| g. as_str ( ) ) . filter ( |s| !s. is_empty ( ) )
12+ type C < ' s , F > = LazyCell < Option < Captures < ' s > > , F > ;
13+
14+ fn get < ' s , F > ( c : & C < ' s , F > , group : usize ) -> Option < Option < & ' s str > >
15+ where
16+ F : FnOnce ( ) -> Option < Captures < ' s > > ,
17+ {
18+ LazyCell :: force ( c)
19+ . as_ref ( )
20+ . map ( |c| c. get ( group) . map ( |g| g. as_str ( ) ) . filter ( |s| !s. is_empty ( ) ) )
1321}
1422
1523// TODO:
@@ -50,21 +58,24 @@ impl<'a> Resolver<'a> {
5058 }
5159 }
5260
53- pub ( crate ) fn resolve ( & ' a self , c : & Captures < ' a > ) -> Cow < ' a , str > {
54- match self {
61+ pub ( crate ) fn resolve < F > ( & ' a self , c : & C < ' a , F > ) -> Option < Cow < ' a , str > >
62+ where
63+ F : FnOnce ( ) -> Option < Captures < ' a > > ,
64+ {
65+ Some ( match self {
5566 Self :: Replacement ( s) => ( * * s) . into ( ) ,
56- Self :: Capture ( i) => get ( c, * i) . unwrap_or ( "" ) . into ( ) ,
67+ Self :: Capture ( i) => get ( c, * i) ? . unwrap_or ( "" ) . into ( ) ,
5768 Self :: Template ( t) => {
5869 let mut r = String :: new ( ) ;
59- c . expand ( t, & mut r) ;
70+ LazyCell :: force ( c ) . as_ref ( ) ? . expand ( t, & mut r) ;
6071 let trimmed = r. trim ( ) ;
6172 if r. len ( ) == trimmed. len ( ) {
6273 r. into ( )
6374 } else {
6475 trimmed. to_string ( ) . into ( )
6576 }
6677 }
67- }
78+ } )
6879 }
6980}
7081
@@ -90,14 +101,17 @@ impl<'a> OptResolver<'a> {
90101 }
91102 }
92103
93- pub ( crate ) fn resolve ( & ' a self , c : & Captures < ' a > ) -> Option < Cow < ' a , str > > {
94- match self {
104+ pub ( crate ) fn resolve < F > ( & ' a self , c : & C < ' a , F > ) -> Option < Option < Cow < ' a , str > > >
105+ where
106+ F : FnOnce ( ) -> Option < Captures < ' a > > ,
107+ {
108+ Some ( match self {
95109 Self :: None => None ,
96110 Self :: Replacement ( s) => Some ( ( * * s) . into ( ) ) ,
97- Self :: Capture ( i) => get ( c, * i) . map ( From :: from) ,
111+ Self :: Capture ( i) => get ( c, * i) ? . map ( From :: from) ,
98112 Self :: Template ( t) => {
99113 let mut r = String :: new ( ) ;
100- c . expand ( t, & mut r) ;
114+ LazyCell :: force ( c ) . as_ref ( ) ? . expand ( t, & mut r) ;
101115 let trimmed = r. trim ( ) ;
102116 if trimmed. is_empty ( ) {
103117 None
@@ -107,7 +121,7 @@ impl<'a> OptResolver<'a> {
107121 Some ( trimmed. to_string ( ) . into ( ) )
108122 }
109123 }
110- }
124+ } )
111125 }
112126}
113127
@@ -135,12 +149,15 @@ impl<'a> FamilyResolver<'a> {
135149 }
136150 }
137151
138- pub ( crate ) fn resolve ( & ' a self , c : & super :: Captures < ' a > ) -> Cow < ' a , str > {
139- match self {
140- FamilyResolver :: Capture => get ( c, 1 ) . unwrap_or ( "" ) . into ( ) ,
152+ pub ( crate ) fn resolve < F > ( & ' a self , c : & C < ' a , F > ) -> Option < Cow < ' a , str > >
153+ where
154+ F : FnOnce ( ) -> Option < Captures < ' a > > ,
155+ {
156+ Some ( match self {
157+ FamilyResolver :: Capture => get ( c, 1 ) ?. unwrap_or ( "" ) . into ( ) ,
141158 FamilyResolver :: Replacement ( s) => ( * * s) . into ( ) ,
142- FamilyResolver :: Template ( t) => t. replace ( "$1" , get ( c, 1 ) . unwrap_or ( "" ) ) . into ( ) ,
143- }
159+ FamilyResolver :: Template ( t) => t. replace ( "$1" , get ( c, 1 ) ? . unwrap_or ( "" ) ) . into ( ) ,
160+ } )
144161 }
145162}
146163
@@ -161,11 +178,14 @@ impl<'a> FallbackResolver<'a> {
161178 Self :: None
162179 }
163180 }
164- pub ( crate ) fn resolve ( & ' a self , c : & super :: Captures < ' a > ) -> Option < & ' a str > {
165- match self {
181+ pub ( crate ) fn resolve < F > ( & ' a self , c : & C < ' a , F > ) -> Option < Option < & ' a str > >
182+ where
183+ F : FnOnce ( ) -> Option < Captures < ' a > > ,
184+ {
185+ Some ( match self {
166186 FallbackResolver :: None => None ,
167- FallbackResolver :: Capture ( n) => get ( c, * n) ,
187+ FallbackResolver :: Capture ( n) => get ( c, * n) ? ,
168188 FallbackResolver :: Replacement ( r) => Some ( r) ,
169- }
189+ } )
170190 }
171191}
0 commit comments