1
1
use super :: { utils, Command , CommandError } ;
2
- use ntex:: util:: Bytes ;
2
+ use ntex:: util:: { Bytes , Either } ;
3
3
use std:: convert:: TryFrom ;
4
4
5
5
use crate :: codec:: { BulkString , Request , Response } ;
@@ -8,76 +8,58 @@ const TYPE_SUBSCRIBE: Bytes = Bytes::from_static(b"subscribe");
8
8
const TYPE_UNSUBSCRIBE : Bytes = Bytes :: from_static ( b"unsubscribe" ) ;
9
9
const TYPE_MESSAGE : Bytes = Bytes :: from_static ( b"message" ) ;
10
10
11
- /// Publish redis command
12
- pub fn Publish < T , V > ( key : T , value : V ) -> utils:: IntOutputCommand
13
- where
14
- BulkString : From < T > + From < V > ,
15
- {
16
- utils:: IntOutputCommand ( Request :: Array ( vec ! [
17
- Request :: from_static( "PUBLISH" ) ,
18
- Request :: BulkString ( key. into( ) ) ,
19
- Request :: BulkString ( value. into( ) ) ,
20
- ] ) )
21
- }
22
-
23
11
#[ derive( Debug , PartialEq ) ]
24
12
pub enum SubscribeItem {
25
- Subscribed ,
26
- UnSubscribed ,
27
- Message ( Bytes ) ,
13
+ Subscribed ( Bytes ) ,
14
+ UnSubscribed ( Bytes ) ,
15
+ Message { channel : Bytes , payload : Bytes } ,
28
16
}
29
17
30
- impl TryFrom < Response > for SubscribeItem {
31
- type Error = CommandError ;
18
+ struct MessagePayload ( Either < Bytes , i64 > ) ;
32
19
33
- fn try_from ( val : Response ) -> Result < Self , Self :: Error > {
34
- let parts = if let Response :: Array ( ref parts) = val {
35
- parts
36
- } else {
37
- return Err ( CommandError :: Output ( "Cannot parse response" , val) ) ;
38
- } ;
20
+ impl TryFrom < Response > for MessagePayload {
21
+ type Error = ( & ' static str , Response ) ;
39
22
40
- if parts . len ( ) != 3 {
41
- return Err ( CommandError :: Output (
42
- "Subscription message has invalid items number" ,
43
- val ,
44
- ) ) ;
23
+ fn try_from ( val : Response ) -> Result < Self , Self :: Error > {
24
+ match val {
25
+ Response :: Bytes ( bytes ) => Ok ( MessagePayload ( Either :: Left ( bytes ) ) ) ,
26
+ Response :: Integer ( number ) => Ok ( MessagePayload ( Either :: Right ( number ) ) ) ,
27
+ _ => Err ( ( "Not a bytes object or integer" , val ) ) ,
45
28
}
29
+ }
30
+ }
46
31
47
- let ( mtype, payload) = ( & parts[ 0 ] , & parts[ 2 ] ) ;
32
+ impl TryFrom < Response > for SubscribeItem {
33
+ type Error = CommandError ;
48
34
49
- let mtype = if let Response :: Bytes ( mtype) = mtype {
50
- mtype
51
- } else {
52
- return Err ( CommandError :: Output (
53
- "Subscription message type unknown" ,
54
- val,
55
- ) ) ;
56
- } ;
35
+ fn try_from ( val : Response ) -> Result < Self , Self :: Error > {
36
+ let ( mtype, channel, payload) = <( Bytes , Bytes , MessagePayload ) >:: try_from ( val) ?;
57
37
58
38
if mtype == & TYPE_SUBSCRIBE {
59
- return Ok ( SubscribeItem :: Subscribed ) ;
39
+ return Ok ( SubscribeItem :: Subscribed ( channel ) ) ;
60
40
}
61
41
62
42
if mtype == & TYPE_UNSUBSCRIBE {
63
- return Ok ( SubscribeItem :: UnSubscribed ) ;
43
+ return Ok ( SubscribeItem :: UnSubscribed ( channel ) ) ;
64
44
}
65
45
66
46
if mtype != & TYPE_MESSAGE {
67
47
return Err ( CommandError :: Output (
68
48
"Subscription message type unknown" ,
69
- val ,
49
+ Response :: Bytes ( mtype ) ,
70
50
) ) ;
71
51
}
72
52
73
- if let Response :: Bytes ( payload) = payload {
74
- return Ok ( SubscribeItem :: Message ( payload. clone ( ) ) ) ;
53
+ let payload = if let Some ( payload) = payload. 0 . left ( ) {
54
+ payload
75
55
} else {
76
56
return Err ( CommandError :: Output (
77
- "Subscription message has empty payload " ,
78
- val ,
57
+ "Subscription message payload is not bytes " ,
58
+ Response :: Nil ,
79
59
) ) ;
80
- }
60
+ } ;
61
+
62
+ Ok ( SubscribeItem :: Message { channel, payload } )
81
63
}
82
64
}
83
65
@@ -95,6 +77,18 @@ impl Command for SubscribeOutputCommand {
95
77
}
96
78
}
97
79
80
+ /// Publish redis command
81
+ pub fn Publish < T , V > ( key : T , value : V ) -> utils:: IntOutputCommand
82
+ where
83
+ BulkString : From < T > + From < V > ,
84
+ {
85
+ utils:: IntOutputCommand ( Request :: Array ( vec ! [
86
+ Request :: from_static( "PUBLISH" ) ,
87
+ Request :: BulkString ( key. into( ) ) ,
88
+ Request :: BulkString ( value. into( ) ) ,
89
+ ] ) )
90
+ }
91
+
98
92
/// Subscribe redis command
99
93
pub fn Subscribe < T > ( key : T ) -> SubscribeOutputCommand
100
94
where
0 commit comments