redis_protocol/convert/
resp3.rs

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
159/// A trait used to convert frames into various other types.
160pub trait FromResp3<F: Resp3Frame>: Sized {
161  /// Convert a frame to the destination type.
162  fn from_frame(frame: F) -> Result<Self, RedisProtocolError>;
163
164  /// Convert multiple frames to the destination type.
165  fn from_frames(frames: Vec<F>) -> Result<Vec<Self>, RedisProtocolError> {
166    frames.into_iter().map(Self::from_frame).collect()
167  }
168
169  // Optional functions that can be used to specialize converting into certain types. Currently, we want to specialize
170  // for `Vec<u8>` and tuples.
171
172  #[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    // TODO make a macro for the duplicated Vec<u8> variants
450    match frame {
451      OwnedFrame::BlobString { data, .. } => {
452        // hacky way to check if T is bytes without consuming `string`
453        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        // hacky way to check if T is bytes without consuming `string`
551        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    // use the `from_value` impl for Vec<T>
645    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    // use the `from_value` impl for Vec<T>
663    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        // this would be cleaner if there were an owned `chunks` variant
843        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        // this would be cleaner if there were an owned `chunks` variant
895        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// Regression tests duplicated for each frame type.
916#[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}