@@ -109,7 +109,7 @@ pub struct ClientIp(pub IpAddr);
109109
110110/// [`ClientIp`] source configuration
111111#[ non_exhaustive]
112- #[ derive( Clone , Debug ) ]
112+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
113113#[ cfg_attr( feature = "serde" , derive( serde:: Deserialize , serde:: Serialize ) ) ]
114114pub enum ClientIpSource {
115115 /// IP from the `CF-Connecting-IP` header
@@ -170,6 +170,23 @@ impl FromStr for ClientIpSource {
170170 }
171171}
172172
173+ // ensure to update tests::client_ip_source_display_impl_matches_from_str_impl
174+ impl fmt:: Display for ClientIpSource {
175+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
176+ f. write_str ( match self {
177+ ClientIpSource :: CfConnectingIp => "CfConnectingIp" ,
178+ ClientIpSource :: CloudFrontViewerAddress => "CloudFrontViewerAddress" ,
179+ ClientIpSource :: ConnectInfo => "ConnectInfo" ,
180+ ClientIpSource :: FlyClientIp => "FlyClientIp" ,
181+ #[ cfg( feature = "forwarded-header" ) ]
182+ ClientIpSource :: RightmostForwarded => "RightmostForwarded" ,
183+ ClientIpSource :: RightmostXForwardedFor => "RightmostXForwardedFor" ,
184+ ClientIpSource :: TrueClientIp => "TrueClientIp" ,
185+ ClientIpSource :: XRealIp => "XRealIp" ,
186+ } )
187+ }
188+ }
189+
173190impl < S > FromRequestParts < S > for ClientIp
174191where
175192 S : Sync ,
@@ -266,7 +283,9 @@ mod tests {
266283
267284 #[ cfg( feature = "forwarded-header" ) ]
268285 use super :: RightmostForwarded ;
269- use super :: { CfConnectingIp , FlyClientIp , RightmostXForwardedFor , TrueClientIp , XRealIp } ;
286+ use super :: {
287+ CfConnectingIp , ClientIpSource , FlyClientIp , RightmostXForwardedFor , TrueClientIp , XRealIp ,
288+ } ;
270289 use crate :: CloudFrontViewerAddress ;
271290
272291 const VALID_IPV4 : & str = "1.2.3.4" ;
@@ -492,4 +511,27 @@ mod tests {
492511 let resp = app ( ) . oneshot ( req) . await . unwrap ( ) ;
493512 assert_eq ! ( body_to_string( resp. into_body( ) ) . await , VALID_IPV6 ) ;
494513 }
514+
515+ #[ test]
516+ fn client_ip_source_display_impl_matches_from_str_impl ( ) {
517+ use std:: str:: FromStr ;
518+
519+ #[ inline]
520+ fn assert_match ( variant : ClientIpSource ) {
521+ assert_eq ! (
522+ variant,
523+ ClientIpSource :: from_str( variant. to_string( ) . as_str( ) ) . unwrap( )
524+ ) ;
525+ }
526+
527+ assert_match ( ClientIpSource :: CfConnectingIp ) ;
528+ assert_match ( ClientIpSource :: CloudFrontViewerAddress ) ;
529+ assert_match ( ClientIpSource :: ConnectInfo ) ;
530+ assert_match ( ClientIpSource :: FlyClientIp ) ;
531+ #[ cfg( feature = "forwarded-header" ) ]
532+ assert_match ( ClientIpSource :: RightmostForwarded ) ;
533+ assert_match ( ClientIpSource :: RightmostXForwardedFor ) ;
534+ assert_match ( ClientIpSource :: TrueClientIp ) ;
535+ assert_match ( ClientIpSource :: XRealIp ) ;
536+ }
495537}
0 commit comments