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
+ }
4
41
5
42
pub fn verify_message_signature < A , R > ( cls : & Class , sel : Sel )
6
- -> Result < ( ) , MessageError >
43
+ -> Result < ( ) , VerificationError >
7
44
where A : EncodeArguments , R : Encode {
8
45
let method = match cls. instance_method ( sel) {
9
46
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) ) ,
14
48
} ;
15
49
16
50
let ret = R :: ENCODING ;
17
51
let expected_ret = method. return_type ( ) ;
18
52
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) ) ;
23
54
}
24
55
25
56
let self_and_cmd = [ <* mut Object >:: ENCODING , Sel :: ENCODING ] ;
@@ -28,19 +59,13 @@ pub fn verify_message_signature<A, R>(cls: &Class, sel: Sel)
28
59
let count = self_and_cmd. len ( ) + args. len ( ) ;
29
60
let expected_count = method. arguments_count ( ) ;
30
61
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) ) ;
35
63
}
36
64
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 ( ) {
38
66
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) ) ;
44
69
}
45
70
}
46
71
0 commit comments