@@ -7,6 +7,7 @@ use std::{
77use clap:: { Args , ValueHint , value_parser} ;
88use semver:: Version ;
99use snafu:: { ResultExt , Snafu , ensure} ;
10+ use strum:: EnumDiscriminants ;
1011use url:: Host ;
1112
1213use crate :: build:: {
@@ -150,7 +151,7 @@ pub fn parse_image_version(input: &str) -> Result<Version, ParseImageVersionErro
150151 Ok ( version)
151152}
152153
153- #[ derive( Debug , PartialEq , Snafu ) ]
154+ #[ derive( Debug , PartialEq , Snafu , EnumDiscriminants ) ]
154155pub enum ParseHostPortError {
155156 #[ snafu( display( "unexpected empty input" ) ) ]
156157 EmptyInput ,
@@ -219,10 +220,29 @@ impl HostPort {
219220#[ cfg( test) ]
220221mod tests {
221222 use rstest:: rstest;
223+ use strum:: IntoDiscriminant ;
222224 use url:: ParseError ;
223225
224226 use super :: * ;
225227
228+ enum Either < L , R > {
229+ Left ( L ) ,
230+ Right ( R ) ,
231+ }
232+
233+ impl < L , R > Either < L , R >
234+ where
235+ L : PartialEq ,
236+ R : PartialEq ,
237+ {
238+ fn is_either ( & self , left : & L , right : & R ) -> bool {
239+ match self {
240+ Either :: Left ( l) => l. eq ( left) ,
241+ Either :: Right ( r) => r. eq ( right) ,
242+ }
243+ }
244+ }
245+
226246 #[ rstest]
227247 #[ case( "registry.example.org:65535" ) ]
228248 #[ case( "registry.example.org:8080" ) ]
@@ -236,19 +256,23 @@ mod tests {
236256 assert_eq ! ( host_port. to_string( ) , input) ;
237257 }
238258
259+ #[ rustfmt:: skip]
239260 #[ rstest]
240- // We use None here, because ParseIntErrors cannot be constructed outside of std. As such, it is
241- // impossible to fully qualify the error we expect in cases where port parsing fails.
242- #[ case( "localhost:65536" , None ) ]
243- #[ case( "localhost:" , None ) ]
244- #[ case( "with space:" , Some ( ParseHostPortError :: InvalidHost { source: ParseError :: IdnaError } ) ) ]
245- #[ case( "with space" , Some ( ParseHostPortError :: InvalidHost { source: ParseError :: IdnaError } ) ) ]
246- #[ case( ":" , Some ( ParseHostPortError :: InvalidHost { source: ParseError :: EmptyHost } ) ) ]
247- #[ case( "" , Some ( ParseHostPortError :: EmptyInput ) ) ]
248- fn invalid_host_port ( #[ case] input : & str , #[ case] expected_error : Option < ParseHostPortError > ) {
261+ // We use the discriminants here, because ParseIntErrors cannot be constructed outside of std.
262+ // As such, it is impossible to fully qualify the error we expect in cases where port parsing
263+ // fails.
264+ #[ case( "localhost:65536" , Either :: Right ( ParseHostPortErrorDiscriminants :: InvalidPort ) ) ]
265+ #[ case( "localhost:" , Either :: Right ( ParseHostPortErrorDiscriminants :: InvalidPort ) ) ]
266+ // Other errors can be fully qualified.
267+ #[ case( "with space:" , Either :: Left ( ParseHostPortError :: InvalidHost { source: ParseError :: IdnaError } ) ) ]
268+ #[ case( "with space" , Either :: Left ( ParseHostPortError :: InvalidHost { source: ParseError :: IdnaError } ) ) ]
269+ #[ case( ":" , Either :: Left ( ParseHostPortError :: InvalidHost { source: ParseError :: EmptyHost } ) ) ]
270+ #[ case( "" , Either :: Left ( ParseHostPortError :: EmptyInput ) ) ]
271+ fn invalid_host_port (
272+ #[ case] input : & str ,
273+ #[ case] expected_error : Either < ParseHostPortError , ParseHostPortErrorDiscriminants > ,
274+ ) {
249275 let error = HostPort :: from_str ( input) . expect_err ( "must not parse" ) ;
250- if let Some ( expected_error) = expected_error {
251- assert_eq ! ( error, expected_error)
252- }
276+ assert ! ( expected_error. is_either( & error, & error. discriminant( ) ) ) ;
253277 }
254278}
0 commit comments