@@ -194,27 +194,33 @@ impl IpAddrs {
194194 None
195195 }
196196
197- pub ( super ) fn split_by_preference ( self , local_addr : Option < IpAddr > ) -> ( IpAddrs , IpAddrs ) {
198- if let Some ( local_addr) = local_addr {
199- let preferred = self
200- . iter
201- . filter ( |addr| addr. is_ipv6 ( ) == local_addr. is_ipv6 ( ) )
202- . collect ( ) ;
203-
204- ( IpAddrs :: new ( preferred) , IpAddrs :: new ( vec ! [ ] ) )
205- } else {
206- let preferring_v6 = self
207- . iter
208- . as_slice ( )
209- . first ( )
210- . map ( SocketAddr :: is_ipv6)
211- . unwrap_or ( false ) ;
212-
213- let ( preferred, fallback) = self
214- . iter
215- . partition :: < Vec < _ > , _ > ( |addr| addr. is_ipv6 ( ) == preferring_v6) ;
216-
217- ( IpAddrs :: new ( preferred) , IpAddrs :: new ( fallback) )
197+ #[ inline]
198+ fn filter ( self , predicate : impl FnMut ( & SocketAddr ) -> bool ) -> IpAddrs {
199+ IpAddrs :: new ( self . iter . filter ( predicate) . collect ( ) )
200+ }
201+
202+ pub ( super ) fn split_by_preference (
203+ self ,
204+ local_addr_ipv4 : Option < Ipv4Addr > ,
205+ local_addr_ipv6 : Option < Ipv6Addr > ,
206+ ) -> ( IpAddrs , IpAddrs ) {
207+ match ( local_addr_ipv4, local_addr_ipv6) {
208+ ( Some ( _) , None ) => ( self . filter ( SocketAddr :: is_ipv4) , IpAddrs :: new ( vec ! [ ] ) ) ,
209+ ( None , Some ( _) ) => ( self . filter ( SocketAddr :: is_ipv6) , IpAddrs :: new ( vec ! [ ] ) ) ,
210+ _ => {
211+ let preferring_v6 = self
212+ . iter
213+ . as_slice ( )
214+ . first ( )
215+ . map ( SocketAddr :: is_ipv6)
216+ . unwrap_or ( false ) ;
217+
218+ let ( preferred, fallback) = self
219+ . iter
220+ . partition :: < Vec < _ > , _ > ( |addr| addr. is_ipv6 ( ) == preferring_v6) ;
221+
222+ ( IpAddrs :: new ( preferred) , IpAddrs :: new ( fallback) )
223+ }
218224 }
219225 }
220226
@@ -349,34 +355,50 @@ mod tests {
349355
350356 #[ test]
351357 fn test_ip_addrs_split_by_preference ( ) {
352- let v4_addr = ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) , 80 ) . into ( ) ;
353- let v6_addr = ( Ipv6Addr :: new ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) , 80 ) . into ( ) ;
358+ let ip_v4 = Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ;
359+ let ip_v6 = Ipv6Addr :: new ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ;
360+ let v4_addr = ( ip_v4, 80 ) . into ( ) ;
361+ let v6_addr = ( ip_v6, 80 ) . into ( ) ;
362+
363+ let ( mut preferred, mut fallback) = IpAddrs {
364+ iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
365+ }
366+ . split_by_preference ( None , None ) ;
367+ assert ! ( preferred. next( ) . unwrap( ) . is_ipv4( ) ) ;
368+ assert ! ( fallback. next( ) . unwrap( ) . is_ipv6( ) ) ;
369+
370+ let ( mut preferred, mut fallback) = IpAddrs {
371+ iter : vec ! [ v6_addr, v4_addr] . into_iter ( ) ,
372+ }
373+ . split_by_preference ( None , None ) ;
374+ assert ! ( preferred. next( ) . unwrap( ) . is_ipv6( ) ) ;
375+ assert ! ( fallback. next( ) . unwrap( ) . is_ipv4( ) ) ;
354376
355377 let ( mut preferred, mut fallback) = IpAddrs {
356378 iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
357379 }
358- . split_by_preference ( None ) ;
380+ . split_by_preference ( Some ( ip_v4 ) , Some ( ip_v6 ) ) ;
359381 assert ! ( preferred. next( ) . unwrap( ) . is_ipv4( ) ) ;
360382 assert ! ( fallback. next( ) . unwrap( ) . is_ipv6( ) ) ;
361383
362384 let ( mut preferred, mut fallback) = IpAddrs {
363385 iter : vec ! [ v6_addr, v4_addr] . into_iter ( ) ,
364386 }
365- . split_by_preference ( None ) ;
387+ . split_by_preference ( Some ( ip_v4 ) , Some ( ip_v6 ) ) ;
366388 assert ! ( preferred. next( ) . unwrap( ) . is_ipv6( ) ) ;
367389 assert ! ( fallback. next( ) . unwrap( ) . is_ipv4( ) ) ;
368390
369391 let ( mut preferred, fallback) = IpAddrs {
370392 iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
371393 }
372- . split_by_preference ( Some ( v4_addr . ip ( ) ) ) ;
394+ . split_by_preference ( Some ( ip_v4 ) , None ) ;
373395 assert ! ( preferred. next( ) . unwrap( ) . is_ipv4( ) ) ;
374396 assert ! ( fallback. is_empty( ) ) ;
375397
376398 let ( mut preferred, fallback) = IpAddrs {
377399 iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
378400 }
379- . split_by_preference ( Some ( v6_addr . ip ( ) ) ) ;
401+ . split_by_preference ( None , Some ( ip_v6 ) ) ;
380402 assert ! ( preferred. next( ) . unwrap( ) . is_ipv6( ) ) ;
381403 assert ! ( fallback. is_empty( ) ) ;
382404 }
0 commit comments