@@ -200,27 +200,33 @@ impl IpAddrs {
200200 None
201201 }
202202
203- pub ( super ) fn split_by_preference ( self , local_addr : Option < IpAddr > ) -> ( IpAddrs , IpAddrs ) {
204- if let Some ( local_addr) = local_addr {
205- let preferred = self
206- . iter
207- . filter ( |addr| addr. is_ipv6 ( ) == local_addr. is_ipv6 ( ) )
208- . collect ( ) ;
209-
210- ( IpAddrs :: new ( preferred) , IpAddrs :: new ( vec ! [ ] ) )
211- } else {
212- let preferring_v6 = self
213- . iter
214- . as_slice ( )
215- . first ( )
216- . map ( SocketAddr :: is_ipv6)
217- . unwrap_or ( false ) ;
218-
219- let ( preferred, fallback) = self
220- . iter
221- . partition :: < Vec < _ > , _ > ( |addr| addr. is_ipv6 ( ) == preferring_v6) ;
222-
223- ( IpAddrs :: new ( preferred) , IpAddrs :: new ( fallback) )
203+ #[ inline]
204+ fn filter ( self , predicate : impl FnMut ( & SocketAddr ) -> bool ) -> IpAddrs {
205+ IpAddrs :: new ( self . iter . filter ( predicate) . collect ( ) )
206+ }
207+
208+ pub ( super ) fn split_by_preference (
209+ self ,
210+ local_addr_ipv4 : Option < Ipv4Addr > ,
211+ local_addr_ipv6 : Option < Ipv6Addr > ,
212+ ) -> ( IpAddrs , IpAddrs ) {
213+ match ( local_addr_ipv4, local_addr_ipv6) {
214+ ( Some ( _) , None ) => ( self . filter ( SocketAddr :: is_ipv4) , IpAddrs :: new ( vec ! [ ] ) ) ,
215+ ( None , Some ( _) ) => ( self . filter ( SocketAddr :: is_ipv6) , IpAddrs :: new ( vec ! [ ] ) ) ,
216+ _ => {
217+ let preferring_v6 = self
218+ . iter
219+ . as_slice ( )
220+ . first ( )
221+ . map ( SocketAddr :: is_ipv6)
222+ . unwrap_or ( false ) ;
223+
224+ let ( preferred, fallback) = self
225+ . iter
226+ . partition :: < Vec < _ > , _ > ( |addr| addr. is_ipv6 ( ) == preferring_v6) ;
227+
228+ ( IpAddrs :: new ( preferred) , IpAddrs :: new ( fallback) )
229+ }
224230 }
225231 }
226232
@@ -355,34 +361,50 @@ mod tests {
355361
356362 #[ test]
357363 fn test_ip_addrs_split_by_preference ( ) {
358- let v4_addr = ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) , 80 ) . into ( ) ;
359- let v6_addr = ( Ipv6Addr :: new ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) , 80 ) . into ( ) ;
364+ let ip_v4 = Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ;
365+ let ip_v6 = Ipv6Addr :: new ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ;
366+ let v4_addr = ( ip_v4, 80 ) . into ( ) ;
367+ let v6_addr = ( ip_v6, 80 ) . into ( ) ;
368+
369+ let ( mut preferred, mut fallback) = IpAddrs {
370+ iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
371+ }
372+ . split_by_preference ( None , None ) ;
373+ assert ! ( preferred. next( ) . unwrap( ) . is_ipv4( ) ) ;
374+ assert ! ( fallback. next( ) . unwrap( ) . is_ipv6( ) ) ;
375+
376+ let ( mut preferred, mut fallback) = IpAddrs {
377+ iter : vec ! [ v6_addr, v4_addr] . into_iter ( ) ,
378+ }
379+ . split_by_preference ( None , None ) ;
380+ assert ! ( preferred. next( ) . unwrap( ) . is_ipv6( ) ) ;
381+ assert ! ( fallback. next( ) . unwrap( ) . is_ipv4( ) ) ;
360382
361383 let ( mut preferred, mut fallback) = IpAddrs {
362384 iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
363385 }
364- . split_by_preference ( None ) ;
386+ . split_by_preference ( Some ( ip_v4 ) , Some ( ip_v6 ) ) ;
365387 assert ! ( preferred. next( ) . unwrap( ) . is_ipv4( ) ) ;
366388 assert ! ( fallback. next( ) . unwrap( ) . is_ipv6( ) ) ;
367389
368390 let ( mut preferred, mut fallback) = IpAddrs {
369391 iter : vec ! [ v6_addr, v4_addr] . into_iter ( ) ,
370392 }
371- . split_by_preference ( None ) ;
393+ . split_by_preference ( Some ( ip_v4 ) , Some ( ip_v6 ) ) ;
372394 assert ! ( preferred. next( ) . unwrap( ) . is_ipv6( ) ) ;
373395 assert ! ( fallback. next( ) . unwrap( ) . is_ipv4( ) ) ;
374396
375397 let ( mut preferred, fallback) = IpAddrs {
376398 iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
377399 }
378- . split_by_preference ( Some ( v4_addr . ip ( ) ) ) ;
400+ . split_by_preference ( Some ( ip_v4 ) , None ) ;
379401 assert ! ( preferred. next( ) . unwrap( ) . is_ipv4( ) ) ;
380402 assert ! ( fallback. is_empty( ) ) ;
381403
382404 let ( mut preferred, fallback) = IpAddrs {
383405 iter : vec ! [ v4_addr, v6_addr] . into_iter ( ) ,
384406 }
385- . split_by_preference ( Some ( v6_addr . ip ( ) ) ) ;
407+ . split_by_preference ( None , Some ( ip_v6 ) ) ;
386408 assert ! ( preferred. next( ) . unwrap( ) . is_ipv6( ) ) ;
387409 assert ! ( fallback. is_empty( ) ) ;
388410 }
0 commit comments