1- use crate :: runtime:: { Class , Object , Sel } ;
2- use crate :: { Encode , EncodeArguments } ;
3- use super :: MessageError ;
1+ use std:: fmt;
2+
3+ use crate :: runtime:: { Class , Method , Object , Sel } ;
4+ use crate :: { Encode , Encoding , EncodeArguments } ;
5+
6+ pub enum VerificationError < ' a > {
7+ NilReceiver ( Sel ) ,
8+ MethodNotFound ( & ' a Class , Sel ) ,
9+ MismatchedReturn ( & ' a Method , Encoding < ' static > ) ,
10+ MismatchedArgumentsCount ( & ' a Method , usize ) ,
11+ MismatchedArgument ( & ' a Method , usize , Encoding < ' static > ) ,
12+ }
13+
14+ impl < ' a > fmt:: Display for VerificationError < ' a > {
15+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
16+ match * self {
17+ VerificationError :: NilReceiver ( sel) => {
18+ write ! ( f, "Messsaging {:?} to nil" , sel)
19+ }
20+ VerificationError :: MethodNotFound ( cls, sel) => {
21+ write ! ( f, "Method {:?} not found on class {:?}" , sel, cls)
22+ }
23+ VerificationError :: MismatchedReturn ( method, ret) => {
24+ let expected_ret = method. return_type ( ) ;
25+ write ! ( f, "Return type code {} does not match expected {} for method {:?}" ,
26+ ret, expected_ret, method. name( ) )
27+ }
28+ VerificationError :: MismatchedArgumentsCount ( method, count) => {
29+ let expected_count = method. arguments_count ( ) ;
30+ write ! ( f, "Method {:?} accepts {} arguments, but {} were given" ,
31+ method. name( ) , expected_count, count)
32+ }
33+ VerificationError :: MismatchedArgument ( method, i, arg) => {
34+ let expected = method. argument_type ( i) . unwrap ( ) ;
35+ write ! ( f, "Method {:?} expected argument at index {} with type code {:?} but was given {:?}" ,
36+ method. name( ) , i, expected, arg)
37+ }
38+ }
39+ }
40+ }
441
542pub fn verify_message_signature < A , R > ( cls : & Class , sel : Sel )
6- -> Result < ( ) , MessageError >
43+ -> Result < ( ) , VerificationError >
744 where A : EncodeArguments , R : Encode {
845 let method = match cls. instance_method ( sel) {
946 Some ( method) => method,
10- None => return Err ( MessageError (
11- format ! ( "Method {:?} not found on class {:?}" ,
12- sel, cls)
13- ) ) ,
47+ None => return Err ( VerificationError :: MethodNotFound ( cls, sel) ) ,
1448 } ;
1549
1650 let ret = R :: ENCODING ;
1751 let expected_ret = method. return_type ( ) ;
1852 if ret != * expected_ret {
19- return Err ( MessageError (
20- format ! ( "Return type code {} does not match expected {} for method {:?}" ,
21- ret, expected_ret, method. name( ) )
22- ) ) ;
53+ return Err ( VerificationError :: MismatchedReturn ( method, ret) ) ;
2354 }
2455
2556 let self_and_cmd = [ <* mut Object >:: ENCODING , Sel :: ENCODING ] ;
@@ -28,19 +59,13 @@ pub fn verify_message_signature<A, R>(cls: &Class, sel: Sel)
2859 let count = self_and_cmd. len ( ) + args. len ( ) ;
2960 let expected_count = method. arguments_count ( ) ;
3061 if count != expected_count {
31- return Err ( MessageError (
32- format ! ( "Method {:?} accepts {} arguments, but {} were given" ,
33- method. name( ) , expected_count, count)
34- ) ) ;
62+ return Err ( VerificationError :: MismatchedArgumentsCount ( method, count) ) ;
3563 }
3664
37- for ( i, arg) in self_and_cmd. iter ( ) . chain ( args) . enumerate ( ) {
65+ for ( i, arg) in self_and_cmd. iter ( ) . chain ( args) . copied ( ) . enumerate ( ) {
3866 let expected = method. argument_type ( i) . unwrap ( ) ;
39- if * arg != * expected {
40- return Err ( MessageError (
41- format ! ( "Method {:?} expected argument at index {} with type code {:?} but was given {:?}" ,
42- method. name( ) , i, expected, arg)
43- ) ) ;
67+ if arg != * expected {
68+ return Err ( VerificationError :: MismatchedArgument ( method, i, arg) ) ;
4469 }
4570 }
4671
0 commit comments