@@ -2,12 +2,12 @@ use crate::{clients::QueueClient, prelude::*, PopReceipt};
2
2
use azure_core:: {
3
3
collect_pinned_stream,
4
4
error:: { ErrorKind , ResultExt } ,
5
- headers:: utc_date_from_rfc2822,
6
5
prelude:: * ,
7
6
Context , Response as AzureResponse ,
8
7
} ;
9
8
use azure_storage:: core:: { headers:: CommonStorageResponseHeaders , xml:: read_xml} ;
10
9
use chrono:: { DateTime , Utc } ;
10
+ use serde:: Deserialize ;
11
11
use std:: convert:: TryInto ;
12
12
13
13
#[ derive( Debug , Clone ) ]
@@ -25,7 +25,6 @@ impl GetMessagesBuilder {
25
25
queue_client,
26
26
number_of_messages : None ,
27
27
visibility_timeout : None ,
28
-
29
28
timeout : None ,
30
29
context : Context :: new ( ) ,
31
30
}
@@ -78,68 +77,105 @@ pub struct GetMessagesResponse {
78
77
pub messages : Vec < Message > ,
79
78
}
80
79
81
- #[ derive( Debug , Clone ) ]
80
+ #[ derive( Debug , Clone , Deserialize ) ]
82
81
pub struct Message {
83
- pub pop_receipt : PopReceipt ,
82
+ #[ serde( rename = "MessageId" ) ]
83
+ message_id : String ,
84
+ #[ serde( rename = "PopReceipt" ) ]
85
+ pop_receipt : String ,
86
+ #[ serde( rename = "InsertionTime" , deserialize_with = "deserialize_utc" ) ]
84
87
pub insertion_time : DateTime < Utc > ,
88
+ #[ serde( rename = "ExpirationTime" , deserialize_with = "deserialize_utc" ) ]
85
89
pub expiration_time : DateTime < Utc > ,
90
+ #[ serde( rename = "TimeNextVisible" , deserialize_with = "deserialize_utc" ) ]
86
91
pub time_next_visible : DateTime < Utc > ,
92
+ #[ serde( rename = "DequeueCount" ) ]
87
93
pub dequeue_count : u64 ,
94
+ #[ serde( rename = "MessageText" ) ]
88
95
pub message_text : String ,
89
96
}
90
97
91
- impl From < Message > for PopReceipt {
92
- fn from ( message : Message ) -> Self {
93
- message . pop_receipt
98
+ impl Message {
99
+ pub fn pop_receipt ( & self ) -> PopReceipt {
100
+ PopReceipt :: new ( self . message_id . clone ( ) , self . pop_receipt . clone ( ) )
94
101
}
95
102
}
96
103
97
- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
98
- struct MessageInternal {
99
- #[ serde( rename = "MessageId" ) ]
100
- pub message_id : String ,
101
- #[ serde( rename = "InsertionTime" ) ]
102
- pub insertion_time : String ,
103
- #[ serde( rename = "ExpirationTime" ) ]
104
- pub expiration_time : String ,
105
- #[ serde( rename = "PopReceipt" ) ]
106
- pub pop_receipt : String ,
107
- #[ serde( rename = "TimeNextVisible" ) ]
108
- pub time_next_visible : String ,
109
- #[ serde( rename = "DequeueCount" ) ]
110
- pub dequeue_count : u64 ,
111
- #[ serde( rename = "MessageText" ) ]
112
- pub message_text : String ,
104
+ impl From < Message > for PopReceipt {
105
+ fn from ( message : Message ) -> Self {
106
+ PopReceipt :: new ( message. message_id , message. pop_receipt )
107
+ }
113
108
}
114
109
115
- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
116
- struct MessagesInternal {
110
+ #[ derive( Debug , Clone , Deserialize ) ]
111
+ struct MessageList {
117
112
#[ serde( rename = "QueueMessage" ) ]
118
- pub messages : Option < Vec < MessageInternal > > ,
113
+ pub messages : Option < Vec < Message > > ,
119
114
}
120
115
121
116
impl GetMessagesResponse {
117
+ fn parse_messages ( body : & [ u8 ] ) -> azure_core:: Result < Vec < Message > > {
118
+ let response: MessageList = read_xml ( body) . map_kind ( ErrorKind :: DataConversion ) ?;
119
+ Ok ( response. messages . unwrap_or_default ( ) )
120
+ }
121
+
122
122
async fn try_from ( response : AzureResponse ) -> azure_core:: Result < Self > {
123
123
let ( _, headers, body) = response. deconstruct ( ) ;
124
124
let body = collect_pinned_stream ( body) . await ?;
125
125
126
- let response: MessagesInternal = read_xml ( & body) . map_kind ( ErrorKind :: DataConversion ) ?;
127
-
128
- let mut messages = Vec :: new ( ) ;
129
- for message in response. messages . unwrap_or_default ( ) . into_iter ( ) {
130
- messages. push ( Message {
131
- pop_receipt : PopReceipt :: new ( message. message_id , message. pop_receipt ) ,
132
- insertion_time : utc_date_from_rfc2822 ( & message. insertion_time ) ?,
133
- expiration_time : utc_date_from_rfc2822 ( & message. expiration_time ) ?,
134
- time_next_visible : utc_date_from_rfc2822 ( & message. time_next_visible ) ?,
135
- dequeue_count : message. dequeue_count ,
136
- message_text : message. message_text ,
137
- } )
138
- }
126
+ let messages = Self :: parse_messages ( & body) ?;
139
127
140
128
Ok ( GetMessagesResponse {
141
129
common_storage_response_headers : ( & headers) . try_into ( ) ?,
142
130
messages,
143
131
} )
144
132
}
145
133
}
134
+
135
+ fn deserialize_utc < ' de , D > ( deserializer : D ) -> std:: result:: Result < DateTime < Utc > , D :: Error >
136
+ where
137
+ D : serde:: Deserializer < ' de > ,
138
+ {
139
+ let s = String :: deserialize ( deserializer) ?;
140
+ let date = DateTime :: parse_from_rfc2822 ( & s) . map_err ( serde:: de:: Error :: custom) ?;
141
+ Ok ( DateTime :: from_utc ( date. naive_utc ( ) , Utc ) )
142
+ }
143
+
144
+ #[ cfg( test) ]
145
+ mod tests {
146
+ use super :: * ;
147
+
148
+ #[ test]
149
+ fn test_parse_messages ( ) -> azure_core:: Result < ( ) > {
150
+ let message = b"\xef \xbb \xbf \
151
+ <?xml version=\" 1.0\" encoding=\" utf-8\" ?>\
152
+ <QueueMessagesList><QueueMessage>\
153
+ <MessageId>00000000-0000-0000-0000-000000000000</MessageId>\
154
+ <InsertionTime>Mon, 27 Jun 2022 13:38:48 GMT</InsertionTime>\
155
+ <ExpirationTime>Mon, 04 Jul 2022 13:38:48 GMT</ExpirationTime>\
156
+ <PopReceipt>REDACTED1</PopReceipt>\
157
+ <TimeNextVisible>Mon, 27 Jun 2022 13:38:53 GMT</TimeNextVisible>\
158
+ <DequeueCount>1</DequeueCount>\
159
+ <MessageText>test1</MessageText>\
160
+ </QueueMessage>\
161
+ <QueueMessage>\
162
+ <MessageId>11111111-1111-1111-1111-111111111111</MessageId>\
163
+ <InsertionTime>Mon, 27 Jun 2022 13:38:48 GMT</InsertionTime>\
164
+ <ExpirationTime>Mon, 04 Jul 2022 13:38:48 GMT</ExpirationTime>\
165
+ <PopReceipt>REDACTED2</PopReceipt>\
166
+ <TimeNextVisible>Mon, 27 Jun 2022 13:38:53 GMT</TimeNextVisible>\
167
+ <DequeueCount>1</DequeueCount>\
168
+ <MessageText>test2</MessageText>\
169
+ </QueueMessage>\
170
+ </QueueMessagesList>\
171
+ ";
172
+
173
+ let messages = GetMessagesResponse :: parse_messages ( message) ?;
174
+
175
+ assert_eq ! ( messages. len( ) , 2 ) ;
176
+ assert_eq ! ( messages[ 0 ] . message_text, "test1" ) ;
177
+ assert_eq ! ( messages[ 1 ] . message_text, "test2" ) ;
178
+
179
+ Ok ( ( ) )
180
+ }
181
+ }
0 commit comments