1use crate::{
2 error::RedisProtocolError,
3 resp3::types::{OwnedFrame, Resp3Frame},
4};
5use alloc::{
6 format,
7 string::{String, ToString},
8 vec,
9 vec::Vec,
10};
11use core::{
12 hash::{BuildHasher, Hash},
13 str,
14};
15
16#[cfg(feature = "bytes")]
17use crate::resp3::types::BytesFrame;
18#[cfg(feature = "bytes")]
19use bytes::Bytes;
20#[cfg(feature = "bytes")]
21use bytes_utils::Str;
22
23use crate::resp3::types::FrameKind;
24#[cfg(feature = "hashbrown")]
25use hashbrown::{HashMap, HashSet};
26#[cfg(feature = "std")]
27use std::collections::{HashMap, HashSet};
28
29macro_rules! to_signed_number(
30 ($f:tt, $t:ty, $v:expr) => {
31 match $v {
32 $f::SimpleError { data, .. } => data.parse::<$t>().map_err(|e| e.into()),
33 $f::Number { data, .. } => Ok(data as $t),
34 $f::Double { data, .. } => Ok(data as $t),
35 $f::SimpleString { data, .. }
36 | $f::BlobString { data, .. }
37 | $f::VerbatimString { data, .. }
38 | $f::BigNumber { data, .. }
39 | $f::ChunkedString(data) => str::from_utf8(&data)
40 .map_err(RedisProtocolError::from)
41 .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
42 $f::Array { mut data, .. } => if data.len() == 1 {
43 match data.pop().unwrap() {
44 $f::SimpleError { data, .. } => data.parse::<$t>().map_err(|e| e.into()),
45 $f::Number { data, .. } => Ok(data as $t),
46 $f::Double { data, .. } => Ok(data as $t),
47 $f::SimpleString { data, .. }
48 | $f::BlobString { data, .. }
49 | $f::VerbatimString { data, .. }
50 | $f::BigNumber { data, .. }
51 | $f::ChunkedString(data) => str::from_utf8(&data)
52 .map_err(RedisProtocolError::from)
53 .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
54 $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
55 _ => Err(RedisProtocolError::new_parse("Cannot convert to number.")),
56 }
57 }else{
58 Err(RedisProtocolError::new_parse("Cannot convert array to number."))
59 }
60 $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
61 _ => Err(RedisProtocolError::new_parse("Cannot convert to number.")),
62 }
63 }
64);
65
66macro_rules! to_unsigned_number(
67 ($f:tt, $t:ty, $v:expr) => {
68 match $v {
69 $f::SimpleError { data, .. } => data.parse::<$t>().map_err(|e| e.into()),
70 $f::Number { data, .. } => if data >= 0 {
71 Ok(data as $t)
72 }else{
73 Err(RedisProtocolError::new_parse("Cannot convert from negative number"))
74 },
75 $f::Double { data, .. } => if data.is_sign_positive() {
76 Ok(data as $t)
77 }else{
78 Err(RedisProtocolError::new_parse("Cannot convert from negative number"))
79 },
80 $f::SimpleString { data, .. }
81 | $f::BlobString { data, .. }
82 | $f::VerbatimString { data, .. }
83 | $f::BigNumber { data, .. }
84 | $f::ChunkedString(data) => str::from_utf8(&data)
85 .map_err(RedisProtocolError::from)
86 .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
87 $f::Array { mut data, .. } => if data.len() == 1 {
88 match data.pop().unwrap() {
89 $f::SimpleError { data, .. } => data.parse::<$t>().map_err(|e| e.into()),
90 $f::Number { data, .. } => if data >= 0 {
91 Ok(data as $t)
92 }else{
93 Err(RedisProtocolError::new_parse("Cannot convert from negative number"))
94 },
95 $f::Double { data, .. } => if data.is_sign_positive() {
96 Ok(data as $t)
97 }else{
98 Err(RedisProtocolError::new_parse("Cannot convert from negative number"))
99 },
100 $f::SimpleString { data, .. }
101 | $f::BlobString { data, .. }
102 | $f::VerbatimString { data, .. }
103 | $f::BigNumber { data, .. }
104 | $f::ChunkedString(data) => str::from_utf8(&data)
105 .map_err(RedisProtocolError::from)
106 .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
107 $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
108 _ => Err(RedisProtocolError::new_parse("Cannot convert to number.")),
109 }
110 }else{
111 Err(RedisProtocolError::new_parse("Cannot convert array to number."))
112 }
113 $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
114 _ => Err(RedisProtocolError::new_parse("Cannot convert to number.")),
115 }
116 }
117);
118
119macro_rules! impl_signed_number (
120 ($t:ty) => {
121 impl FromResp3<OwnedFrame> for $t {
122 fn from_frame(value: OwnedFrame) -> Result<$t, RedisProtocolError> {
123 check_single_vec_reply!(value);
124 to_signed_number!(OwnedFrame, $t, value)
125 }
126 }
127
128 #[cfg(feature = "bytes")]
129 #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
130 impl FromResp3<BytesFrame> for $t {
131 fn from_frame(value: BytesFrame) -> Result<$t, RedisProtocolError> {
132 check_single_vec_reply!(value);
133 to_signed_number!(BytesFrame, $t, value)
134 }
135 }
136 }
137);
138
139macro_rules! impl_unsigned_number (
140 ($t:ty) => {
141 impl FromResp3<OwnedFrame> for $t {
142 fn from_frame(value: OwnedFrame) -> Result<$t, RedisProtocolError> {
143 check_single_vec_reply!(value);
144 to_unsigned_number!(OwnedFrame, $t, value)
145 }
146 }
147
148 #[cfg(feature = "bytes")]
149 #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
150 impl FromResp3<BytesFrame> for $t {
151 fn from_frame(value: BytesFrame) -> Result<$t, RedisProtocolError> {
152 check_single_vec_reply!(value);
153 to_unsigned_number!(BytesFrame, $t, value)
154 }
155 }
156 }
157);
158
159pub trait FromResp3<F: Resp3Frame>: Sized {
161 fn from_frame(frame: F) -> Result<Self, RedisProtocolError>;
163
164 fn from_frames(frames: Vec<F>) -> Result<Vec<Self>, RedisProtocolError> {
166 frames.into_iter().map(Self::from_frame).collect()
167 }
168
169 #[doc(hidden)]
173 fn is_tuple() -> bool {
174 false
175 }
176
177 #[doc(hidden)]
178 fn from_owned_bytes(_: Vec<u8>) -> Option<Vec<Self>> {
179 None
180 }
181}
182
183impl_signed_number!(i8);
184impl_signed_number!(i16);
185impl_signed_number!(i32);
186impl_signed_number!(i64);
187impl_signed_number!(i128);
188impl_signed_number!(isize);
189
190impl FromResp3<OwnedFrame> for u8 {
191 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
192 check_single_vec_reply!(frame);
193 to_unsigned_number!(OwnedFrame, u8, frame)
194 }
195
196 fn from_owned_bytes(d: Vec<u8>) -> Option<Vec<Self>> {
197 Some(d)
198 }
199}
200#[cfg(feature = "bytes")]
201#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
202impl FromResp3<BytesFrame> for u8 {
203 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
204 check_single_vec_reply!(frame);
205 to_unsigned_number!(BytesFrame, u8, frame)
206 }
207
208 fn from_owned_bytes(d: Vec<u8>) -> Option<Vec<Self>> {
209 Some(d)
210 }
211}
212
213impl_unsigned_number!(u16);
214impl_unsigned_number!(u32);
215impl_unsigned_number!(u64);
216impl_unsigned_number!(u128);
217impl_unsigned_number!(usize);
218
219impl FromResp3<OwnedFrame> for f64 {
220 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
221 check_single_vec_reply!(frame);
222
223 frame
224 .as_f64()
225 .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
226 }
227}
228#[cfg(feature = "bytes")]
229#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
230impl FromResp3<BytesFrame> for f64 {
231 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
232 check_single_vec_reply!(frame);
233
234 frame
235 .as_f64()
236 .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
237 }
238}
239
240impl FromResp3<OwnedFrame> for f32 {
241 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
242 check_single_vec_reply!(frame);
243
244 frame
245 .as_f64()
246 .map(|f| f as f32)
247 .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
248 }
249}
250#[cfg(feature = "bytes")]
251#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
252impl FromResp3<BytesFrame> for f32 {
253 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
254 check_single_vec_reply!(frame);
255
256 frame
257 .as_f64()
258 .map(|f| f as f32)
259 .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
260 }
261}
262
263impl FromResp3<OwnedFrame> for bool {
264 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
265 check_single_vec_reply!(frame);
266
267 frame
268 .as_bool()
269 .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to bool"))
270 }
271}
272#[cfg(feature = "bytes")]
273#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
274impl FromResp3<BytesFrame> for bool {
275 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
276 check_single_vec_reply!(frame);
277
278 frame
279 .as_bool()
280 .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to bool"))
281 }
282}
283
284impl FromResp3<OwnedFrame> for () {
285 fn from_frame(_: OwnedFrame) -> Result<Self, RedisProtocolError> {
286 Ok(())
287 }
288}
289#[cfg(feature = "bytes")]
290#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
291impl FromResp3<BytesFrame> for () {
292 fn from_frame(_: BytesFrame) -> Result<Self, RedisProtocolError> {
293 Ok(())
294 }
295}
296
297impl FromResp3<OwnedFrame> for OwnedFrame {
298 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
299 Ok(frame)
300 }
301}
302#[cfg(feature = "bytes")]
303#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
304impl FromResp3<BytesFrame> for BytesFrame {
305 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
306 Ok(frame)
307 }
308}
309
310impl FromResp3<OwnedFrame> for String {
311 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
312 debug_type!("FromResp3(String): {:?}", frame);
313 check_single_vec_reply!(frame);
314
315 Ok(match frame {
316 OwnedFrame::SimpleError { data, .. } => data,
317 OwnedFrame::SimpleString { data, .. }
318 | OwnedFrame::BlobString { data, .. }
319 | OwnedFrame::BlobError { data, .. }
320 | OwnedFrame::VerbatimString { data, .. }
321 | OwnedFrame::BigNumber { data, .. }
322 | OwnedFrame::ChunkedString(data) => String::from_utf8(data)?,
323 OwnedFrame::Number { data, .. } => data.to_string(),
324 OwnedFrame::Double { data, .. } => data.to_string(),
325 OwnedFrame::Boolean { data, .. } => data.to_string(),
326 _ => return Err(RedisProtocolError::new_parse("Cannot convert to string.")),
327 })
328 }
329}
330#[cfg(feature = "bytes")]
331#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
332impl FromResp3<BytesFrame> for String {
333 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
334 debug_type!("FromResp3(String): {:?}", frame);
335 check_single_vec_reply!(frame);
336
337 Ok(match frame {
338 BytesFrame::SimpleError { data, .. } => data.to_string(),
339 BytesFrame::SimpleString { data, .. }
340 | BytesFrame::BlobString { data, .. }
341 | BytesFrame::BlobError { data, .. }
342 | BytesFrame::VerbatimString { data, .. }
343 | BytesFrame::BigNumber { data, .. }
344 | BytesFrame::ChunkedString(data) => String::from_utf8(data.to_vec())?,
345 BytesFrame::Number { data, .. } => data.to_string(),
346 BytesFrame::Double { data, .. } => data.to_string(),
347 BytesFrame::Boolean { data, .. } => data.to_string(),
348 _ => return Err(RedisProtocolError::new_parse("Cannot convert to string.")),
349 })
350 }
351}
352
353#[cfg(feature = "bytes")]
354#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
355impl FromResp3<BytesFrame> for Str {
356 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
357 debug_type!("FromResp3(Str): {:?}", frame);
358 check_single_vec_reply!(frame);
359
360 Ok(match frame {
361 BytesFrame::SimpleError { data, .. } => data.to_string().into(),
362 BytesFrame::SimpleString { data, .. }
363 | BytesFrame::BlobString { data, .. }
364 | BytesFrame::BlobError { data, .. }
365 | BytesFrame::VerbatimString { data, .. }
366 | BytesFrame::BigNumber { data, .. }
367 | BytesFrame::ChunkedString(data) => Str::from_inner(data)?,
368 BytesFrame::Number { data, .. } => data.to_string().into(),
369 BytesFrame::Double { data, .. } => data.to_string().into(),
370 BytesFrame::Boolean { data, .. } => data.to_string().into(),
371 _ => return Err(RedisProtocolError::new_parse("Cannot convert to string.")),
372 })
373 }
374}
375
376#[cfg(feature = "bytes")]
377#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
378impl FromResp3<BytesFrame> for Bytes {
379 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
380 debug_type!("FromResp3(Bytes): {:?}", frame);
381 check_single_vec_reply!(frame);
382
383 Ok(match frame {
384 BytesFrame::SimpleError { data, .. } => data.into_inner(),
385 BytesFrame::SimpleString { data, .. }
386 | BytesFrame::BlobString { data, .. }
387 | BytesFrame::BlobError { data, .. }
388 | BytesFrame::VerbatimString { data, .. }
389 | BytesFrame::BigNumber { data, .. }
390 | BytesFrame::ChunkedString(data) => data,
391 BytesFrame::Number { data, .. } => data.to_string().into(),
392 BytesFrame::Double { data, .. } => data.to_string().into(),
393 BytesFrame::Boolean { data, .. } => data.to_string().into(),
394 _ => return Err(RedisProtocolError::new_parse("Cannot convert to bytes.")),
395 })
396 }
397}
398
399impl<T> FromResp3<OwnedFrame> for Option<T>
400where
401 T: FromResp3<OwnedFrame>,
402{
403 fn from_frame(frame: OwnedFrame) -> Result<Option<T>, RedisProtocolError> {
404 debug_type!("FromResp3(Option<{}>): {:?}", std::any::type_name::<T>(), frame);
405
406 match frame {
407 OwnedFrame::Array { data, attributes } => {
408 if data.is_empty() {
409 Ok(None)
410 } else {
411 T::from_frame(OwnedFrame::Array { data, attributes }).map(Some)
412 }
413 },
414 OwnedFrame::Null => Ok(None),
415 _ => T::from_frame(frame).map(Some),
416 }
417 }
418}
419#[cfg(feature = "bytes")]
420#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
421impl<T> FromResp3<BytesFrame> for Option<T>
422where
423 T: FromResp3<BytesFrame>,
424{
425 fn from_frame(frame: BytesFrame) -> Result<Option<T>, RedisProtocolError> {
426 debug_type!("FromResp3(Option<{}>): {:?}", std::any::type_name::<T>(), frame);
427
428 match frame {
429 BytesFrame::Array { data, attributes } => {
430 if data.is_empty() {
431 Ok(None)
432 } else {
433 T::from_frame(BytesFrame::Array { data, attributes }).map(Some)
434 }
435 },
436 BytesFrame::Null => Ok(None),
437 _ => T::from_frame(frame).map(Some),
438 }
439 }
440}
441
442impl<T> FromResp3<OwnedFrame> for Vec<T>
443where
444 T: FromResp3<OwnedFrame>,
445{
446 fn from_frame(frame: OwnedFrame) -> Result<Vec<T>, RedisProtocolError> {
447 debug_type!("FromResp3(Vec<{}>): {:?}", std::any::type_name::<T>(), frame);
448
449 match frame {
451 OwnedFrame::BlobString { data, .. } => {
452 if T::from_owned_bytes(Vec::new()).is_some() {
454 T::from_owned_bytes(data).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
455 } else {
456 Ok(vec![T::from_frame(OwnedFrame::BlobString { data, attributes: None })?])
457 }
458 },
459 OwnedFrame::BlobError { data, .. } => {
460 if T::from_owned_bytes(Vec::new()).is_some() {
461 T::from_owned_bytes(data).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
462 } else {
463 Ok(vec![T::from_frame(OwnedFrame::BlobError { data, attributes: None })?])
464 }
465 },
466 OwnedFrame::SimpleString { data, .. } => {
467 if T::from_owned_bytes(Vec::new()).is_some() {
468 T::from_owned_bytes(data).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
469 } else {
470 Ok(vec![T::from_frame(OwnedFrame::SimpleString {
471 data,
472 attributes: None,
473 })?])
474 }
475 },
476 OwnedFrame::VerbatimString { data, format, .. } => {
477 if T::from_owned_bytes(Vec::new()).is_some() {
478 T::from_owned_bytes(data).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
479 } else {
480 Ok(vec![T::from_frame(OwnedFrame::VerbatimString {
481 data,
482 format,
483 attributes: None,
484 })?])
485 }
486 },
487 OwnedFrame::BigNumber { data, .. } => {
488 if T::from_owned_bytes(Vec::new()).is_some() {
489 T::from_owned_bytes(data).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
490 } else {
491 Ok(vec![T::from_frame(OwnedFrame::BigNumber { data, attributes: None })?])
492 }
493 },
494 OwnedFrame::SimpleError { data, .. } => {
495 if T::from_owned_bytes(Vec::new()).is_some() {
496 T::from_owned_bytes(data.into_bytes()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
497 } else {
498 Ok(vec![T::from_frame(OwnedFrame::SimpleError { data, attributes: None })?])
499 }
500 },
501 OwnedFrame::ChunkedString(data) => {
502 if T::from_owned_bytes(Vec::new()).is_some() {
503 T::from_owned_bytes(data).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
504 } else {
505 Ok(vec![T::from_frame(OwnedFrame::ChunkedString(data))?])
506 }
507 },
508 OwnedFrame::Boolean { data, .. } => Ok(vec![T::from_frame(OwnedFrame::Boolean { data, attributes: None })?]),
509 OwnedFrame::Number { data, .. } => Ok(vec![T::from_frame(OwnedFrame::Number { data, attributes: None })?]),
510 OwnedFrame::Double { data, .. } => Ok(vec![T::from_frame(OwnedFrame::Double { data, attributes: None })?]),
511 OwnedFrame::Null => Ok(Vec::new()),
512
513 OwnedFrame::Array { data, .. } | OwnedFrame::Push { data, .. } => {
514 if !data.is_empty() {
515 let kind = data[0].kind();
516 if matches!(kind, FrameKind::Array | FrameKind::Push) {
517 data.into_iter().map(|x| T::from_frame(x)).collect()
518 } else {
519 T::from_frames(data)
520 }
521 } else {
522 Ok(Vec::new())
523 }
524 },
525 OwnedFrame::Set { data, .. } => data.into_iter().map(|x| T::from_frame(x)).collect(),
526 OwnedFrame::Map { data, .. } => {
527 let mut out = Vec::with_capacity(data.len() * 2);
528 for (key, value) in data.into_iter() {
529 out.push(T::from_frame(key)?);
530 out.push(T::from_frame(value)?);
531 }
532 Ok(out)
533 },
534 _ => Err(RedisProtocolError::new_parse("Could not convert to array.")),
535 }
536 }
537}
538
539#[cfg(feature = "bytes")]
540#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
541impl<T> FromResp3<BytesFrame> for Vec<T>
542where
543 T: FromResp3<BytesFrame>,
544{
545 fn from_frame(frame: BytesFrame) -> Result<Vec<T>, RedisProtocolError> {
546 debug_type!("FromResp3(Vec<{}>): {:?}", std::any::type_name::<T>(), frame);
547
548 match frame {
549 BytesFrame::BlobString { data, .. } => {
550 if T::from_owned_bytes(Vec::new()).is_some() {
552 T::from_owned_bytes(data.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
553 } else {
554 Ok(vec![T::from_frame(BytesFrame::BlobString { data, attributes: None })?])
555 }
556 },
557 BytesFrame::BlobError { data, .. } => {
558 if T::from_owned_bytes(Vec::new()).is_some() {
559 T::from_owned_bytes(data.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
560 } else {
561 Ok(vec![T::from_frame(BytesFrame::BlobError { data, attributes: None })?])
562 }
563 },
564 BytesFrame::SimpleString { data, .. } => {
565 if T::from_owned_bytes(Vec::new()).is_some() {
566 T::from_owned_bytes(data.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
567 } else {
568 Ok(vec![T::from_frame(BytesFrame::SimpleString {
569 data,
570 attributes: None,
571 })?])
572 }
573 },
574 BytesFrame::VerbatimString { data, format, .. } => {
575 if T::from_owned_bytes(Vec::new()).is_some() {
576 T::from_owned_bytes(data.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
577 } else {
578 Ok(vec![T::from_frame(BytesFrame::VerbatimString {
579 data,
580 format,
581 attributes: None,
582 })?])
583 }
584 },
585 BytesFrame::BigNumber { data, .. } => {
586 if T::from_owned_bytes(Vec::new()).is_some() {
587 T::from_owned_bytes(data.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
588 } else {
589 Ok(vec![T::from_frame(BytesFrame::BigNumber { data, attributes: None })?])
590 }
591 },
592 BytesFrame::SimpleError { data, .. } => {
593 if T::from_owned_bytes(Vec::new()).is_some() {
594 T::from_owned_bytes(data.as_bytes().to_vec())
595 .ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
596 } else {
597 Ok(vec![T::from_frame(BytesFrame::SimpleError { data, attributes: None })?])
598 }
599 },
600 BytesFrame::ChunkedString(data) => {
601 if T::from_owned_bytes(Vec::new()).is_some() {
602 T::from_owned_bytes(data.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
603 } else {
604 Ok(vec![T::from_frame(BytesFrame::ChunkedString(data))?])
605 }
606 },
607 BytesFrame::Boolean { data, .. } => Ok(vec![T::from_frame(BytesFrame::Boolean { data, attributes: None })?]),
608 BytesFrame::Number { data, .. } => Ok(vec![T::from_frame(BytesFrame::Number { data, attributes: None })?]),
609 BytesFrame::Double { data, .. } => Ok(vec![T::from_frame(BytesFrame::Double { data, attributes: None })?]),
610 BytesFrame::Null => Ok(Vec::new()),
611
612 BytesFrame::Array { data, .. } | BytesFrame::Push { data, .. } => {
613 if !data.is_empty() {
614 let kind = data[0].kind();
615 if matches!(kind, FrameKind::Array | FrameKind::Push) {
616 data.into_iter().map(|x| T::from_frame(x)).collect()
617 } else {
618 T::from_frames(data)
619 }
620 } else {
621 Ok(Vec::new())
622 }
623 },
624 BytesFrame::Set { data, .. } => data.into_iter().map(|x| T::from_frame(x)).collect(),
625 BytesFrame::Map { data, .. } => {
626 let mut out = Vec::with_capacity(data.len() * 2);
627 for (key, value) in data.into_iter() {
628 out.push(T::from_frame(key)?);
629 out.push(T::from_frame(value)?);
630 }
631 Ok(out)
632 },
633 _ => Err(RedisProtocolError::new_parse("Could not convert to array.")),
634 }
635 }
636}
637
638impl<T, const N: usize> FromResp3<OwnedFrame> for [T; N]
639where
640 T: FromResp3<OwnedFrame>,
641{
642 fn from_frame(value: OwnedFrame) -> Result<[T; N], RedisProtocolError> {
643 debug_type!("FromResp3([{}; {}]): {:?}", std::any::type_name::<T>(), N, value);
644 let value: Vec<T> = value.convert()?;
646 let len = value.len();
647
648 value.try_into().map_err(|_| {
649 RedisProtocolError::new_parse(format!("Failed to convert to array. Expected {}, found {}.", N, len))
650 })
651 }
652}
653
654#[cfg(feature = "bytes")]
655#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
656impl<T, const N: usize> FromResp3<BytesFrame> for [T; N]
657where
658 T: FromResp3<BytesFrame>,
659{
660 fn from_frame(value: BytesFrame) -> Result<[T; N], RedisProtocolError> {
661 debug_type!("FromResp3([{}; {}]): {:?}", std::any::type_name::<T>(), N, value);
662 let value: Vec<T> = value.convert()?;
664 let len = value.len();
665
666 value.try_into().map_err(|_| {
667 RedisProtocolError::new_parse(format!("Failed to convert to array. Expected {}, found {}.", N, len))
668 })
669 }
670}
671
672impl<K, V, S> FromResp3<OwnedFrame> for HashMap<K, V, S>
673where
674 K: FromResp3<OwnedFrame> + Eq + Hash,
675 V: FromResp3<OwnedFrame>,
676 S: BuildHasher + Default,
677{
678 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
679 debug_type!(
680 "FromResp3(HashMap<{}, {}>): {:?}",
681 std::any::type_name::<K>(),
682 std::any::type_name::<V>(),
683 frame
684 );
685
686 match frame {
687 OwnedFrame::Array { mut data, .. } | OwnedFrame::Push { mut data, .. } => {
688 if data.is_empty() {
689 return Ok::<HashMap<K, V, S>, _>(HashMap::default());
690 }
691
692 if data.len() % 2 == 0 {
693 let mut out = HashMap::default();
694 out.reserve(data.len() / 2);
695
696 #[allow(clippy::manual_while_let_some)]
697 while !data.is_empty() {
698 let value = data.pop().unwrap();
699 let key = data.pop().unwrap();
700
701 out.insert(K::from_frame(key)?, V::from_frame(value)?);
702 }
703 Ok(out)
704 } else {
705 Err(RedisProtocolError::new_parse("Expected even number of elements"))
706 }
707 },
708 OwnedFrame::Map { data, .. } => data
709 .into_iter()
710 .map(|(k, v)| Ok((K::from_frame(k)?, V::from_frame(v)?)))
711 .collect(),
712 _ => Err(RedisProtocolError::new_parse("Cannot convert to map")),
713 }
714 }
715}
716
717#[cfg(feature = "bytes")]
718#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
719impl<K, V, S> FromResp3<BytesFrame> for HashMap<K, V, S>
720where
721 K: FromResp3<BytesFrame> + Eq + Hash,
722 V: FromResp3<BytesFrame>,
723 S: BuildHasher + Default,
724{
725 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
726 debug_type!(
727 "FromResp3(HashMap<{}, {}>): {:?}",
728 std::any::type_name::<K>(),
729 std::any::type_name::<V>(),
730 frame
731 );
732
733 match frame {
734 BytesFrame::Array { mut data, .. } | BytesFrame::Push { mut data, .. } => {
735 if data.is_empty() {
736 return Ok::<HashMap<K, V, S>, _>(HashMap::default());
737 }
738
739 if data.len() % 2 == 0 {
740 let mut out = HashMap::default();
741 out.reserve(data.len() / 2);
742
743 #[allow(clippy::manual_while_let_some)]
744 while !data.is_empty() {
745 let value = data.pop().unwrap();
746 let key = data.pop().unwrap();
747
748 out.insert(K::from_frame(key)?, V::from_frame(value)?);
749 }
750 Ok(out)
751 } else {
752 Err(RedisProtocolError::new_parse("Expected even number of elements"))
753 }
754 },
755 BytesFrame::Map { data, .. } => data
756 .into_iter()
757 .map(|(k, v)| Ok((K::from_frame(k)?, V::from_frame(v)?)))
758 .collect(),
759 _ => Err(RedisProtocolError::new_parse("Cannot convert to map")),
760 }
761 }
762}
763
764impl<V, S> FromResp3<OwnedFrame> for HashSet<V, S>
765where
766 V: FromResp3<OwnedFrame> + Hash + Eq,
767 S: BuildHasher + Default,
768{
769 fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
770 debug_type!("FromResp3(HashSet<{}>): {:?}", std::any::type_name::<V>(), frame);
771
772 match frame {
773 OwnedFrame::Array { data, .. } | OwnedFrame::Push { data, .. } => data.into_iter().map(V::from_frame).collect(),
774 OwnedFrame::Set { data, .. } => data.into_iter().map(V::from_frame).collect(),
775 _ => Err(RedisProtocolError::new_parse("Cannot convert to set")),
776 }
777 }
778}
779
780#[cfg(feature = "bytes")]
781#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
782impl<V, S> FromResp3<BytesFrame> for HashSet<V, S>
783where
784 V: FromResp3<BytesFrame> + Hash + Eq,
785 S: BuildHasher + Default,
786{
787 fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
788 debug_type!("FromResp3(HashSet<{}>): {:?}", std::any::type_name::<V>(), frame);
789
790 match frame {
791 BytesFrame::Array { data, .. } | BytesFrame::Push { data, .. } => data.into_iter().map(V::from_frame).collect(),
792 BytesFrame::Set { data, .. } => data.into_iter().map(V::from_frame).collect(),
793 _ => Err(RedisProtocolError::new_parse("Cannot convert to set")),
794 }
795 }
796}
797
798macro_rules! impl_from_resp3_tuple {
799 () => ();
800 ($($name:ident,)+) => (
801 #[doc(hidden)]
802 #[cfg(feature = "bytes")]
803 impl<$($name: FromResp3<BytesFrame>),*> FromResp3<BytesFrame> for ($($name,)*) {
804 fn is_tuple() -> bool {
805 true
806 }
807
808 #[allow(non_snake_case, unused_variables)]
809 fn from_frame(v: BytesFrame) -> Result<($($name,)*), RedisProtocolError> {
810 let mut values: Vec<_> = match v {
811 BytesFrame::Array { data, .. } => data,
812 BytesFrame::Push { data, .. } => data,
813 BytesFrame::Set { data, .. } => data.into_iter().collect(),
814 _ => return Err(RedisProtocolError::new_parse("Could not convert to tuple."))
815 };
816
817 let mut n = 0;
818 $(let $name = (); n += 1;)*
819 debug_type!("FromResp3({}-tuple): {:?}", n, values);
820 if values.len() != n {
821 return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
822 }
823
824 values.reverse();
825 Ok(($({let $name = (); values
826 .pop()
827 .ok_or(RedisProtocolError::new_parse("Expected value, found none."))?
828 .convert()?
829 },)*))
830 }
831
832 #[allow(non_snake_case, unused_variables)]
833 fn from_frames(mut values: Vec<BytesFrame>) -> Result<Vec<($($name,)*)>, RedisProtocolError> {
834 let mut n = 0;
835 $(let $name = (); n += 1;)*
836 debug_type!("FromResp3({}-tuple): {:?}", n, values);
837 if values.len() % n != 0 {
838 return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
839 }
840
841 let mut out = Vec::with_capacity(values.len() / n);
842 for chunk in values.chunks_exact_mut(n) {
844 match chunk {
845 [$($name),*] => out.push(($($name.take().convert()?),*),),
846 _ => unreachable!(),
847 }
848 }
849
850 Ok(out)
851 }
852 }
853
854 #[doc(hidden)]
855 impl<$($name: FromResp3<OwnedFrame>),*> FromResp3<OwnedFrame> for ($($name,)*) {
856 fn is_tuple() -> bool {
857 true
858 }
859
860 #[allow(non_snake_case, unused_variables)]
861 fn from_frame(v: OwnedFrame) -> Result<($($name,)*), RedisProtocolError> {
862 let mut values: Vec<_> = match v {
863 OwnedFrame::Array { data, .. } => data,
864 OwnedFrame::Push { data, .. } => data,
865 OwnedFrame::Set { data, .. } => data.into_iter().collect(),
866 _ => return Err(RedisProtocolError::new_parse("Could not convert to tuple."))
867 };
868
869 let mut n = 0;
870 $(let $name = (); n += 1;)*
871 debug_type!("FromResp3({}-tuple): {:?}", n, values);
872 if values.len() != n {
873 return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
874 }
875
876 values.reverse();
877 Ok(($({let $name = (); values
878 .pop()
879 .ok_or(RedisProtocolError::new_parse("Expected value, found none."))?
880 .convert()?
881 },)*))
882 }
883
884 #[allow(non_snake_case, unused_variables)]
885 fn from_frames(mut values: Vec<OwnedFrame>) -> Result<Vec<($($name,)*)>, RedisProtocolError> {
886 let mut n = 0;
887 $(let $name = (); n += 1;)*
888 debug_type!("FromResp3({}-tuple): {:?}", n, values);
889 if values.len() % n != 0 {
890 return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
891 }
892
893 let mut out = Vec::with_capacity(values.len() / n);
894 for chunk in values.chunks_exact_mut(n) {
896 match chunk {
897 [$($name),*] => out.push(($($name.take().convert()?),*),),
898 _ => unreachable!(),
899 }
900 }
901
902 Ok(out)
903 }
904 }
905 impl_from_resp3_peel!($($name,)*);
906 )
907}
908
909macro_rules! impl_from_resp3_peel {
910 ($name:ident, $($other:ident,)*) => (impl_from_resp3_tuple!($($other,)*);)
911}
912
913impl_from_resp3_tuple! { T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
914
915#[cfg(test)]
917mod owned_tests {
918 use super::*;
919
920 #[test]
921 fn should_convert_signed_numeric_types() {
922 let _foo: i8 = OwnedFrame::BlobString {
923 data: "123".into(),
924 attributes: None,
925 }
926 .convert()
927 .unwrap();
928 assert_eq!(_foo, 123);
929 let _foo: i8 = OwnedFrame::Number {
930 data: 123,
931 attributes: None,
932 }
933 .convert()
934 .unwrap();
935 assert_eq!(_foo, 123);
936 let _foo: i16 = OwnedFrame::BlobString {
937 data: "123".into(),
938 attributes: None,
939 }
940 .convert()
941 .unwrap();
942 assert_eq!(_foo, 123);
943 let _foo: i16 = OwnedFrame::Number {
944 data: 123,
945 attributes: None,
946 }
947 .convert()
948 .unwrap();
949 assert_eq!(_foo, 123);
950 let _foo: i32 = OwnedFrame::BlobString {
951 data: "123".into(),
952 attributes: None,
953 }
954 .convert()
955 .unwrap();
956 assert_eq!(_foo, 123);
957 let _foo: i32 = OwnedFrame::Number {
958 data: 123,
959 attributes: None,
960 }
961 .convert()
962 .unwrap();
963 assert_eq!(_foo, 123);
964 let _foo: i64 = OwnedFrame::BlobString {
965 data: "123".into(),
966 attributes: None,
967 }
968 .convert()
969 .unwrap();
970 assert_eq!(_foo, 123);
971 let _foo: i64 = OwnedFrame::Number {
972 data: 123,
973 attributes: None,
974 }
975 .convert()
976 .unwrap();
977 assert_eq!(_foo, 123);
978 let _foo: i128 = OwnedFrame::BlobString {
979 data: "123".into(),
980 attributes: None,
981 }
982 .convert()
983 .unwrap();
984 assert_eq!(_foo, 123);
985 let _foo: i128 = OwnedFrame::Number {
986 data: 123,
987 attributes: None,
988 }
989 .convert()
990 .unwrap();
991 assert_eq!(_foo, 123);
992 let _foo: isize = OwnedFrame::BlobString {
993 data: "123".into(),
994 attributes: None,
995 }
996 .convert()
997 .unwrap();
998 assert_eq!(_foo, 123);
999 let _foo: isize = OwnedFrame::Number {
1000 data: 123,
1001 attributes: None,
1002 }
1003 .convert()
1004 .unwrap();
1005 assert_eq!(_foo, 123);
1006 let _foo: f32 = OwnedFrame::BlobString {
1007 data: "123.5".into(),
1008 attributes: None,
1009 }
1010 .convert()
1011 .unwrap();
1012 assert_eq!(_foo, 123.5);
1013 let _foo: f64 = OwnedFrame::BlobString {
1014 data: "123.5".into(),
1015 attributes: None,
1016 }
1017 .convert()
1018 .unwrap();
1019 assert_eq!(_foo, 123.5);
1020 }
1021
1022 #[test]
1023 fn should_convert_unsigned_numeric_types() {
1024 let _foo: u8 = OwnedFrame::BlobString {
1025 data: "123".into(),
1026 attributes: None,
1027 }
1028 .convert()
1029 .unwrap();
1030 assert_eq!(_foo, 123);
1031 let _foo: u8 = OwnedFrame::Number {
1032 data: 123,
1033 attributes: None,
1034 }
1035 .convert()
1036 .unwrap();
1037 assert_eq!(_foo, 123);
1038 let _foo: u16 = OwnedFrame::BlobString {
1039 data: "123".into(),
1040 attributes: None,
1041 }
1042 .convert()
1043 .unwrap();
1044 assert_eq!(_foo, 123);
1045 let _foo: u16 = OwnedFrame::Number {
1046 data: 123,
1047 attributes: None,
1048 }
1049 .convert()
1050 .unwrap();
1051 assert_eq!(_foo, 123);
1052 let _foo: u32 = OwnedFrame::BlobString {
1053 data: "123".into(),
1054 attributes: None,
1055 }
1056 .convert()
1057 .unwrap();
1058 assert_eq!(_foo, 123);
1059 let _foo: u32 = OwnedFrame::Number {
1060 data: 123,
1061 attributes: None,
1062 }
1063 .convert()
1064 .unwrap();
1065 assert_eq!(_foo, 123);
1066 let _foo: u64 = OwnedFrame::BlobString {
1067 data: "123".into(),
1068 attributes: None,
1069 }
1070 .convert()
1071 .unwrap();
1072 assert_eq!(_foo, 123);
1073 let _foo: u64 = OwnedFrame::Number {
1074 data: 123,
1075 attributes: None,
1076 }
1077 .convert()
1078 .unwrap();
1079 assert_eq!(_foo, 123);
1080 let _foo: u128 = OwnedFrame::BlobString {
1081 data: "123".into(),
1082 attributes: None,
1083 }
1084 .convert()
1085 .unwrap();
1086 assert_eq!(_foo, 123);
1087 let _foo: u128 = OwnedFrame::Number {
1088 data: 123,
1089 attributes: None,
1090 }
1091 .convert()
1092 .unwrap();
1093 assert_eq!(_foo, 123);
1094 let _foo: usize = OwnedFrame::BlobString {
1095 data: "123".into(),
1096 attributes: None,
1097 }
1098 .convert()
1099 .unwrap();
1100 assert_eq!(_foo, 123);
1101 let _foo: usize = OwnedFrame::Number {
1102 data: 123,
1103 attributes: None,
1104 }
1105 .convert()
1106 .unwrap();
1107 assert_eq!(_foo, 123);
1108 }
1109
1110 #[test]
1111 fn should_return_not_found_with_null_number_types() {
1112 let result: Result<u8, _> = OwnedFrame::Null.convert();
1113 assert!(result.is_err());
1114 let result: Result<u16, _> = OwnedFrame::Null.convert();
1115 assert!(result.is_err());
1116 let result: Result<u32, _> = OwnedFrame::Null.convert();
1117 assert!(result.is_err());
1118 let result: Result<u64, _> = OwnedFrame::Null.convert();
1119 assert!(result.is_err());
1120 let result: Result<u128, _> = OwnedFrame::Null.convert();
1121 assert!(result.is_err());
1122 let result: Result<usize, _> = OwnedFrame::Null.convert();
1123 assert!(result.is_err());
1124 let result: Result<i8, _> = OwnedFrame::Null.convert();
1125 assert!(result.is_err());
1126 let result: Result<i16, _> = OwnedFrame::Null.convert();
1127 assert!(result.is_err());
1128 let result: Result<i32, _> = OwnedFrame::Null.convert();
1129 assert!(result.is_err());
1130 let result: Result<i64, _> = OwnedFrame::Null.convert();
1131 assert!(result.is_err());
1132 let result: Result<i128, _> = OwnedFrame::Null.convert();
1133 assert!(result.is_err());
1134 let result: Result<isize, _> = OwnedFrame::Null.convert();
1135 assert!(result.is_err());
1136 }
1137
1138 #[test]
1139 fn should_convert_strings() {
1140 let _foo: String = OwnedFrame::BlobString {
1141 data: "foo".into(),
1142 attributes: None,
1143 }
1144 .convert()
1145 .unwrap();
1146 assert_eq!(_foo, "foo".to_owned());
1147 }
1148
1149 #[test]
1150 fn should_convert_numbers_to_bools() {
1151 let foo: bool = OwnedFrame::Number {
1152 data: 0,
1153 attributes: None,
1154 }
1155 .convert()
1156 .unwrap();
1157 assert!(!foo);
1158 let foo: bool = OwnedFrame::Number {
1159 data: 1,
1160 attributes: None,
1161 }
1162 .convert()
1163 .unwrap();
1164 assert!(foo);
1165 let foo: bool = OwnedFrame::BlobString {
1166 data: "0".into(),
1167 attributes: None,
1168 }
1169 .convert()
1170 .unwrap();
1171 assert!(!foo);
1172 let foo: bool = OwnedFrame::BlobString {
1173 data: "1".into(),
1174 attributes: None,
1175 }
1176 .convert()
1177 .unwrap();
1178 assert!(foo);
1179 }
1180
1181 #[test]
1182 fn should_convert_bytes() {
1183 let foo: Vec<u8> = OwnedFrame::BlobString {
1184 data: "foo".as_bytes().to_vec(),
1185 attributes: None,
1186 }
1187 .convert()
1188 .unwrap();
1189 assert_eq!(foo, "foo".as_bytes().to_vec());
1190 let foo: Vec<u8> = OwnedFrame::BlobString {
1191 data: "foo".into(),
1192 attributes: None,
1193 }
1194 .convert()
1195 .unwrap();
1196 assert_eq!(foo, "foo".as_bytes().to_vec());
1197 let foo: Vec<u8> = OwnedFrame::Array {
1198 data: vec![
1199 OwnedFrame::Number {
1200 data: 102,
1201 attributes: None,
1202 },
1203 OwnedFrame::Number {
1204 data: 111,
1205 attributes: None,
1206 },
1207 OwnedFrame::Number {
1208 data: 111,
1209 attributes: None,
1210 },
1211 ],
1212 attributes: None,
1213 }
1214 .convert()
1215 .unwrap();
1216 assert_eq!(foo, "foo".as_bytes().to_vec());
1217 }
1218
1219 #[test]
1220 fn should_convert_arrays() {
1221 let foo: Vec<String> = OwnedFrame::Array {
1222 data: vec![
1223 OwnedFrame::SimpleString {
1224 data: "a".into(),
1225 attributes: None,
1226 },
1227 OwnedFrame::SimpleString {
1228 data: "b".into(),
1229 attributes: None,
1230 },
1231 ],
1232 attributes: None,
1233 }
1234 .convert()
1235 .unwrap();
1236 assert_eq!(foo, vec!["a".to_owned(), "b".to_owned()]);
1237 }
1238
1239 #[test]
1240 fn should_convert_hash_maps() {
1241 let foo: HashMap<String, u16> = OwnedFrame::Array {
1242 data: vec![
1243 OwnedFrame::SimpleString {
1244 data: "a".into(),
1245 attributes: None,
1246 },
1247 OwnedFrame::Number {
1248 data: 1,
1249 attributes: None,
1250 },
1251 OwnedFrame::SimpleString {
1252 data: "b".into(),
1253 attributes: None,
1254 },
1255 OwnedFrame::Number {
1256 data: 2,
1257 attributes: None,
1258 },
1259 ],
1260 attributes: None,
1261 }
1262 .convert()
1263 .unwrap();
1264
1265 let mut expected = HashMap::new();
1266 expected.insert("a".to_owned(), 1);
1267 expected.insert("b".to_owned(), 2);
1268 assert_eq!(foo, expected);
1269 }
1270
1271 #[test]
1272 fn should_convert_hash_sets() {
1273 let foo: HashSet<String> = OwnedFrame::Array {
1274 data: vec![
1275 OwnedFrame::SimpleString {
1276 data: "a".into(),
1277 attributes: None,
1278 },
1279 OwnedFrame::SimpleString {
1280 data: "b".into(),
1281 attributes: None,
1282 },
1283 ],
1284 attributes: None,
1285 }
1286 .convert()
1287 .unwrap();
1288
1289 let mut expected = HashSet::new();
1290 expected.insert("a".to_owned());
1291 expected.insert("b".to_owned());
1292 assert_eq!(foo, expected);
1293
1294 let foo: HashSet<String> = OwnedFrame::Set {
1295 data: vec![
1296 OwnedFrame::SimpleString {
1297 data: "a".into(),
1298 attributes: None,
1299 },
1300 OwnedFrame::SimpleString {
1301 data: "b".into(),
1302 attributes: None,
1303 },
1304 ]
1305 .into_iter()
1306 .collect(),
1307 attributes: None,
1308 }
1309 .convert()
1310 .unwrap();
1311
1312 let mut expected = HashSet::new();
1313 expected.insert("a".to_owned());
1314 expected.insert("b".to_owned());
1315 assert_eq!(foo, expected);
1316 }
1317
1318 #[test]
1319 fn should_convert_tuples() {
1320 let foo: (String, i64) = OwnedFrame::Array {
1321 data: vec![
1322 OwnedFrame::SimpleString {
1323 data: "a".into(),
1324 attributes: None,
1325 },
1326 OwnedFrame::Number {
1327 data: 1,
1328 attributes: None,
1329 },
1330 ],
1331 attributes: None,
1332 }
1333 .convert()
1334 .unwrap();
1335 assert_eq!(foo, ("a".to_owned(), 1));
1336 }
1337
1338 #[test]
1339 fn should_convert_array_tuples() {
1340 let foo: Vec<(String, i64)> = OwnedFrame::Array {
1341 data: vec![
1342 OwnedFrame::SimpleString {
1343 data: "a".into(),
1344 attributes: None,
1345 },
1346 OwnedFrame::Number {
1347 data: 1,
1348 attributes: None,
1349 },
1350 OwnedFrame::SimpleString {
1351 data: "b".into(),
1352 attributes: None,
1353 },
1354 OwnedFrame::Number {
1355 data: 2,
1356 attributes: None,
1357 },
1358 ],
1359 attributes: None,
1360 }
1361 .convert()
1362 .unwrap();
1363 assert_eq!(foo, vec![("a".to_owned(), 1), ("b".to_owned(), 2)]);
1364 }
1365
1366 #[test]
1367 fn should_handle_single_element_vector_to_scalar() {
1368 assert!(OwnedFrame::Array {
1369 data: vec![],
1370 attributes: None,
1371 }
1372 .convert::<String>()
1373 .is_err());
1374 assert_eq!(
1375 OwnedFrame::Array {
1376 data: vec![OwnedFrame::SimpleString {
1377 data: "foo".into(),
1378 attributes: None,
1379 }],
1380 attributes: None,
1381 }
1382 .convert::<String>(),
1383 Ok("foo".into())
1384 );
1385 assert!(OwnedFrame::Array {
1386 data: vec![
1387 OwnedFrame::SimpleString {
1388 data: "foo".into(),
1389 attributes: None,
1390 },
1391 OwnedFrame::SimpleString {
1392 data: "bar".into(),
1393 attributes: None,
1394 }
1395 ],
1396 attributes: None,
1397 }
1398 .convert::<String>()
1399 .is_err());
1400
1401 assert_eq!(
1402 OwnedFrame::Array {
1403 data: vec![],
1404 attributes: None,
1405 }
1406 .convert::<Option<String>>(),
1407 Ok(None)
1408 );
1409 assert_eq!(
1410 OwnedFrame::Array {
1411 data: vec![OwnedFrame::SimpleString {
1412 data: "foo".into(),
1413 attributes: None,
1414 }],
1415 attributes: None,
1416 }
1417 .convert::<Option<String>>(),
1418 Ok(Some("foo".into()))
1419 );
1420 assert!(OwnedFrame::Array {
1421 data: vec![
1422 OwnedFrame::SimpleString {
1423 data: "foo".into(),
1424 attributes: None,
1425 },
1426 OwnedFrame::SimpleString {
1427 data: "bar".into(),
1428 attributes: None,
1429 }
1430 ],
1431 attributes: None,
1432 }
1433 .convert::<Option<String>>()
1434 .is_err());
1435 }
1436
1437 #[test]
1438 fn should_convert_null_to_empty_array() {
1439 assert_eq!(Vec::<String>::new(), OwnedFrame::Null.convert::<Vec<String>>().unwrap());
1440 assert_eq!(Vec::<u8>::new(), OwnedFrame::Null.convert::<Vec<u8>>().unwrap());
1441 }
1442
1443 #[test]
1444 fn should_convert_to_fixed_arrays() {
1445 let foo: [i64; 2] = OwnedFrame::Array {
1446 data: vec![
1447 OwnedFrame::Number {
1448 data: 1,
1449 attributes: None,
1450 },
1451 OwnedFrame::Number {
1452 data: 2,
1453 attributes: None,
1454 },
1455 ],
1456 attributes: None,
1457 }
1458 .convert()
1459 .unwrap();
1460 assert_eq!(foo, [1, 2]);
1461
1462 assert!(OwnedFrame::Array {
1463 data: vec![
1464 OwnedFrame::Number {
1465 data: 1,
1466 attributes: None,
1467 },
1468 OwnedFrame::Number {
1469 data: 2,
1470 attributes: None,
1471 }
1472 ],
1473 attributes: None,
1474 }
1475 .convert::<[i64; 3]>()
1476 .is_err());
1477 assert!(OwnedFrame::Array {
1478 data: vec![],
1479 attributes: None,
1480 }
1481 .convert::<[i64; 3]>()
1482 .is_err());
1483 }
1484}
1485
1486#[cfg(test)]
1487#[cfg(feature = "bytes")]
1488mod bytes_tests {
1489 use super::*;
1490
1491 #[test]
1492 fn should_convert_signed_numeric_types() {
1493 let _foo: i8 = BytesFrame::BlobString {
1494 data: "123".into(),
1495 attributes: None,
1496 }
1497 .convert()
1498 .unwrap();
1499 assert_eq!(_foo, 123);
1500 let _foo: i8 = BytesFrame::Number {
1501 data: 123,
1502 attributes: None,
1503 }
1504 .convert()
1505 .unwrap();
1506 assert_eq!(_foo, 123);
1507 let _foo: i16 = BytesFrame::BlobString {
1508 data: "123".into(),
1509 attributes: None,
1510 }
1511 .convert()
1512 .unwrap();
1513 assert_eq!(_foo, 123);
1514 let _foo: i16 = BytesFrame::Number {
1515 data: 123,
1516 attributes: None,
1517 }
1518 .convert()
1519 .unwrap();
1520 assert_eq!(_foo, 123);
1521 let _foo: i32 = BytesFrame::BlobString {
1522 data: "123".into(),
1523 attributes: None,
1524 }
1525 .convert()
1526 .unwrap();
1527 assert_eq!(_foo, 123);
1528 let _foo: i32 = BytesFrame::Number {
1529 data: 123,
1530 attributes: None,
1531 }
1532 .convert()
1533 .unwrap();
1534 assert_eq!(_foo, 123);
1535 let _foo: i64 = BytesFrame::BlobString {
1536 data: "123".into(),
1537 attributes: None,
1538 }
1539 .convert()
1540 .unwrap();
1541 assert_eq!(_foo, 123);
1542 let _foo: i64 = BytesFrame::Number {
1543 data: 123,
1544 attributes: None,
1545 }
1546 .convert()
1547 .unwrap();
1548 assert_eq!(_foo, 123);
1549 let _foo: i128 = BytesFrame::BlobString {
1550 data: "123".into(),
1551 attributes: None,
1552 }
1553 .convert()
1554 .unwrap();
1555 assert_eq!(_foo, 123);
1556 let _foo: i128 = BytesFrame::Number {
1557 data: 123,
1558 attributes: None,
1559 }
1560 .convert()
1561 .unwrap();
1562 assert_eq!(_foo, 123);
1563 let _foo: isize = BytesFrame::BlobString {
1564 data: "123".into(),
1565 attributes: None,
1566 }
1567 .convert()
1568 .unwrap();
1569 assert_eq!(_foo, 123);
1570 let _foo: isize = BytesFrame::Number {
1571 data: 123,
1572 attributes: None,
1573 }
1574 .convert()
1575 .unwrap();
1576 assert_eq!(_foo, 123);
1577 let _foo: f32 = BytesFrame::BlobString {
1578 data: "123.5".into(),
1579 attributes: None,
1580 }
1581 .convert()
1582 .unwrap();
1583 assert_eq!(_foo, 123.5);
1584 let _foo: f64 = BytesFrame::BlobString {
1585 data: "123.5".into(),
1586 attributes: None,
1587 }
1588 .convert()
1589 .unwrap();
1590 assert_eq!(_foo, 123.5);
1591 }
1592
1593 #[test]
1594 fn should_convert_unsigned_numeric_types() {
1595 let _foo: u8 = BytesFrame::BlobString {
1596 data: "123".into(),
1597 attributes: None,
1598 }
1599 .convert()
1600 .unwrap();
1601 assert_eq!(_foo, 123);
1602 let _foo: u8 = BytesFrame::Number {
1603 data: 123,
1604 attributes: None,
1605 }
1606 .convert()
1607 .unwrap();
1608 assert_eq!(_foo, 123);
1609 let _foo: u16 = BytesFrame::BlobString {
1610 data: "123".into(),
1611 attributes: None,
1612 }
1613 .convert()
1614 .unwrap();
1615 assert_eq!(_foo, 123);
1616 let _foo: u16 = BytesFrame::Number {
1617 data: 123,
1618 attributes: None,
1619 }
1620 .convert()
1621 .unwrap();
1622 assert_eq!(_foo, 123);
1623 let _foo: u32 = BytesFrame::BlobString {
1624 data: "123".into(),
1625 attributes: None,
1626 }
1627 .convert()
1628 .unwrap();
1629 assert_eq!(_foo, 123);
1630 let _foo: u32 = BytesFrame::Number {
1631 data: 123,
1632 attributes: None,
1633 }
1634 .convert()
1635 .unwrap();
1636 assert_eq!(_foo, 123);
1637 let _foo: u64 = BytesFrame::BlobString {
1638 data: "123".into(),
1639 attributes: None,
1640 }
1641 .convert()
1642 .unwrap();
1643 assert_eq!(_foo, 123);
1644 let _foo: u64 = BytesFrame::Number {
1645 data: 123,
1646 attributes: None,
1647 }
1648 .convert()
1649 .unwrap();
1650 assert_eq!(_foo, 123);
1651 let _foo: u128 = BytesFrame::BlobString {
1652 data: "123".into(),
1653 attributes: None,
1654 }
1655 .convert()
1656 .unwrap();
1657 assert_eq!(_foo, 123);
1658 let _foo: u128 = BytesFrame::Number {
1659 data: 123,
1660 attributes: None,
1661 }
1662 .convert()
1663 .unwrap();
1664 assert_eq!(_foo, 123);
1665 let _foo: usize = BytesFrame::BlobString {
1666 data: "123".into(),
1667 attributes: None,
1668 }
1669 .convert()
1670 .unwrap();
1671 assert_eq!(_foo, 123);
1672 let _foo: usize = BytesFrame::Number {
1673 data: 123,
1674 attributes: None,
1675 }
1676 .convert()
1677 .unwrap();
1678 assert_eq!(_foo, 123);
1679 }
1680
1681 #[test]
1682 fn should_return_not_found_with_null_number_types() {
1683 let result: Result<u8, _> = BytesFrame::Null.convert();
1684 assert!(result.is_err());
1685 let result: Result<u16, _> = BytesFrame::Null.convert();
1686 assert!(result.is_err());
1687 let result: Result<u32, _> = BytesFrame::Null.convert();
1688 assert!(result.is_err());
1689 let result: Result<u64, _> = BytesFrame::Null.convert();
1690 assert!(result.is_err());
1691 let result: Result<u128, _> = BytesFrame::Null.convert();
1692 assert!(result.is_err());
1693 let result: Result<usize, _> = BytesFrame::Null.convert();
1694 assert!(result.is_err());
1695 let result: Result<i8, _> = BytesFrame::Null.convert();
1696 assert!(result.is_err());
1697 let result: Result<i16, _> = BytesFrame::Null.convert();
1698 assert!(result.is_err());
1699 let result: Result<i32, _> = BytesFrame::Null.convert();
1700 assert!(result.is_err());
1701 let result: Result<i64, _> = BytesFrame::Null.convert();
1702 assert!(result.is_err());
1703 let result: Result<i128, _> = BytesFrame::Null.convert();
1704 assert!(result.is_err());
1705 let result: Result<isize, _> = BytesFrame::Null.convert();
1706 assert!(result.is_err());
1707 }
1708
1709 #[test]
1710 fn should_convert_strings() {
1711 let _foo: String = BytesFrame::BlobString {
1712 data: "foo".into(),
1713 attributes: None,
1714 }
1715 .convert()
1716 .unwrap();
1717 assert_eq!(_foo, "foo".to_owned());
1718 }
1719
1720 #[test]
1721 fn should_convert_bytes_util_str() {
1722 let _foo: Str = BytesFrame::BlobString {
1723 data: "foo".into(),
1724 attributes: None,
1725 }
1726 .convert()
1727 .unwrap();
1728 assert_eq!(_foo, Str::from("foo"));
1729 }
1730
1731 #[test]
1732 fn should_convert_bytes_bytes() {
1733 let _foo: Bytes = BytesFrame::BlobString {
1734 data: "foo".into(),
1735 attributes: None,
1736 }
1737 .convert()
1738 .unwrap();
1739 assert_eq!(_foo, Bytes::from("foo"));
1740 }
1741
1742 #[test]
1743 fn should_convert_numbers_to_bools() {
1744 let foo: bool = BytesFrame::Number {
1745 data: 0,
1746 attributes: None,
1747 }
1748 .convert()
1749 .unwrap();
1750 assert!(!foo);
1751 let foo: bool = BytesFrame::Number {
1752 data: 1,
1753 attributes: None,
1754 }
1755 .convert()
1756 .unwrap();
1757 assert!(foo);
1758 let foo: bool = BytesFrame::BlobString {
1759 data: "0".into(),
1760 attributes: None,
1761 }
1762 .convert()
1763 .unwrap();
1764 assert!(!foo);
1765 let foo: bool = BytesFrame::BlobString {
1766 data: "1".into(),
1767 attributes: None,
1768 }
1769 .convert()
1770 .unwrap();
1771 assert!(foo);
1772 }
1773
1774 #[test]
1775 fn should_convert_bytes() {
1776 let foo: Vec<u8> = BytesFrame::BlobString {
1777 data: "foo".as_bytes().to_vec().into(),
1778 attributes: None,
1779 }
1780 .convert()
1781 .unwrap();
1782 assert_eq!(foo, "foo".as_bytes().to_vec());
1783 let foo: Vec<u8> = BytesFrame::BlobString {
1784 data: "foo".into(),
1785 attributes: None,
1786 }
1787 .convert()
1788 .unwrap();
1789 assert_eq!(foo, "foo".as_bytes().to_vec());
1790 let foo: Vec<u8> = BytesFrame::Array {
1791 data: vec![
1792 BytesFrame::Number {
1793 data: 102,
1794 attributes: None,
1795 },
1796 BytesFrame::Number {
1797 data: 111,
1798 attributes: None,
1799 },
1800 BytesFrame::Number {
1801 data: 111,
1802 attributes: None,
1803 },
1804 ],
1805 attributes: None,
1806 }
1807 .convert()
1808 .unwrap();
1809 assert_eq!(foo, "foo".as_bytes().to_vec());
1810 }
1811
1812 #[test]
1813 fn should_convert_arrays() {
1814 let foo: Vec<String> = BytesFrame::Array {
1815 data: vec![
1816 BytesFrame::SimpleString {
1817 data: "a".into(),
1818 attributes: None,
1819 },
1820 BytesFrame::SimpleString {
1821 data: "b".into(),
1822 attributes: None,
1823 },
1824 ],
1825 attributes: None,
1826 }
1827 .convert()
1828 .unwrap();
1829 assert_eq!(foo, vec!["a".to_owned(), "b".to_owned()]);
1830 }
1831
1832 #[test]
1833 fn should_convert_hash_maps() {
1834 let foo: HashMap<String, u16> = BytesFrame::Array {
1835 data: vec![
1836 BytesFrame::SimpleString {
1837 data: "a".into(),
1838 attributes: None,
1839 },
1840 BytesFrame::Number {
1841 data: 1,
1842 attributes: None,
1843 },
1844 BytesFrame::SimpleString {
1845 data: "b".into(),
1846 attributes: None,
1847 },
1848 BytesFrame::Number {
1849 data: 2,
1850 attributes: None,
1851 },
1852 ],
1853 attributes: None,
1854 }
1855 .convert()
1856 .unwrap();
1857
1858 let mut expected = HashMap::new();
1859 expected.insert("a".to_owned(), 1);
1860 expected.insert("b".to_owned(), 2);
1861 assert_eq!(foo, expected);
1862 }
1863
1864 #[test]
1865 fn should_convert_hash_sets() {
1866 let foo: HashSet<String> = BytesFrame::Array {
1867 data: vec![
1868 BytesFrame::SimpleString {
1869 data: "a".into(),
1870 attributes: None,
1871 },
1872 BytesFrame::SimpleString {
1873 data: "b".into(),
1874 attributes: None,
1875 },
1876 ],
1877 attributes: None,
1878 }
1879 .convert()
1880 .unwrap();
1881
1882 let mut expected = HashSet::new();
1883 expected.insert("a".to_owned());
1884 expected.insert("b".to_owned());
1885 assert_eq!(foo, expected);
1886
1887 let foo: HashSet<String> = BytesFrame::Set {
1888 data: vec![
1889 BytesFrame::SimpleString {
1890 data: "a".into(),
1891 attributes: None,
1892 },
1893 BytesFrame::SimpleString {
1894 data: "b".into(),
1895 attributes: None,
1896 },
1897 ]
1898 .into_iter()
1899 .collect(),
1900 attributes: None,
1901 }
1902 .convert()
1903 .unwrap();
1904
1905 let mut expected = HashSet::new();
1906 expected.insert("a".to_owned());
1907 expected.insert("b".to_owned());
1908 assert_eq!(foo, expected);
1909 }
1910
1911 #[test]
1912 fn should_convert_tuples() {
1913 let foo: (String, i64) = BytesFrame::Array {
1914 data: vec![
1915 BytesFrame::SimpleString {
1916 data: "a".into(),
1917 attributes: None,
1918 },
1919 BytesFrame::Number {
1920 data: 1,
1921 attributes: None,
1922 },
1923 ],
1924 attributes: None,
1925 }
1926 .convert()
1927 .unwrap();
1928 assert_eq!(foo, ("a".to_owned(), 1));
1929 }
1930
1931 #[test]
1932 fn should_convert_array_tuples() {
1933 let foo: Vec<(String, i64)> = BytesFrame::Array {
1934 data: vec![
1935 BytesFrame::SimpleString {
1936 data: "a".into(),
1937 attributes: None,
1938 },
1939 BytesFrame::Number {
1940 data: 1,
1941 attributes: None,
1942 },
1943 BytesFrame::SimpleString {
1944 data: "b".into(),
1945 attributes: None,
1946 },
1947 BytesFrame::Number {
1948 data: 2,
1949 attributes: None,
1950 },
1951 ],
1952 attributes: None,
1953 }
1954 .convert()
1955 .unwrap();
1956 assert_eq!(foo, vec![("a".to_owned(), 1), ("b".to_owned(), 2)]);
1957 }
1958
1959 #[test]
1960 fn should_handle_single_element_vector_to_scalar() {
1961 assert!(BytesFrame::Array {
1962 data: vec![],
1963 attributes: None,
1964 }
1965 .convert::<String>()
1966 .is_err());
1967 assert_eq!(
1968 BytesFrame::Array {
1969 data: vec![BytesFrame::SimpleString {
1970 data: "foo".into(),
1971 attributes: None,
1972 }],
1973 attributes: None,
1974 }
1975 .convert::<String>(),
1976 Ok("foo".into())
1977 );
1978 assert!(BytesFrame::Array {
1979 data: vec![
1980 BytesFrame::SimpleString {
1981 data: "foo".into(),
1982 attributes: None,
1983 },
1984 BytesFrame::SimpleString {
1985 data: "bar".into(),
1986 attributes: None,
1987 }
1988 ],
1989 attributes: None,
1990 }
1991 .convert::<String>()
1992 .is_err());
1993
1994 assert_eq!(
1995 BytesFrame::Array {
1996 data: vec![],
1997 attributes: None,
1998 }
1999 .convert::<Option<String>>(),
2000 Ok(None)
2001 );
2002 assert_eq!(
2003 BytesFrame::Array {
2004 data: vec![BytesFrame::SimpleString {
2005 data: "foo".into(),
2006 attributes: None,
2007 }],
2008 attributes: None,
2009 }
2010 .convert::<Option<String>>(),
2011 Ok(Some("foo".into()))
2012 );
2013 assert!(BytesFrame::Array {
2014 data: vec![
2015 BytesFrame::SimpleString {
2016 data: "foo".into(),
2017 attributes: None,
2018 },
2019 BytesFrame::SimpleString {
2020 data: "bar".into(),
2021 attributes: None,
2022 }
2023 ],
2024 attributes: None,
2025 }
2026 .convert::<Option<String>>()
2027 .is_err());
2028 }
2029
2030 #[test]
2031 fn should_convert_null_to_empty_array() {
2032 assert_eq!(Vec::<String>::new(), BytesFrame::Null.convert::<Vec<String>>().unwrap());
2033 assert_eq!(Vec::<u8>::new(), BytesFrame::Null.convert::<Vec<u8>>().unwrap());
2034 }
2035
2036 #[test]
2037 fn should_convert_to_fixed_arrays() {
2038 let foo: [i64; 2] = BytesFrame::Array {
2039 data: vec![
2040 BytesFrame::Number {
2041 data: 1,
2042 attributes: None,
2043 },
2044 BytesFrame::Number {
2045 data: 2,
2046 attributes: None,
2047 },
2048 ],
2049 attributes: None,
2050 }
2051 .convert()
2052 .unwrap();
2053 assert_eq!(foo, [1, 2]);
2054
2055 assert!(BytesFrame::Array {
2056 data: vec![
2057 BytesFrame::Number {
2058 data: 1,
2059 attributes: None,
2060 },
2061 BytesFrame::Number {
2062 data: 2,
2063 attributes: None,
2064 }
2065 ],
2066 attributes: None,
2067 }
2068 .convert::<[i64; 3]>()
2069 .is_err());
2070 assert!(BytesFrame::Array {
2071 data: vec![],
2072 attributes: None,
2073 }
2074 .convert::<[i64; 3]>()
2075 .is_err());
2076 }
2077}