redis_protocol/convert/
resp2.rs

1use crate::{
2  error::RedisProtocolError,
3  resp2::types::{OwnedFrame, Resp2Frame},
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::resp2::types::BytesFrame;
18#[cfg(feature = "bytes")]
19use bytes::Bytes;
20#[cfg(feature = "bytes")]
21use bytes_utils::Str;
22
23#[cfg(feature = "hashbrown")]
24use hashbrown::{HashMap, HashSet};
25#[cfg(feature = "std")]
26use std::collections::{HashMap, HashSet};
27
28macro_rules! to_signed_number(
29  ($f:tt, $t:ty, $v:expr) => {
30    match $v {
31      $f::Error(s) => s.parse::<$t>().map_err(|e| e.into()),
32      $f::Integer(i) => Ok(i as $t),
33      $f::SimpleString(s) | $f::BulkString(s) => str::from_utf8(&s)
34        .map_err(RedisProtocolError::from)
35        .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
36      $f::Array(mut a) => if a.len() == 1 {
37        match a.pop().unwrap() {
38          $f::Error(s) => s.parse::<$t>().map_err(|e| e.into()),
39          $f::Integer(i) => Ok(i as $t),
40          $f::SimpleString(s) | $f::BulkString(s) => str::from_utf8(&s)
41            .map_err(RedisProtocolError::from)
42            .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
43          $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
44          _ => Err(RedisProtocolError::new_parse("Cannot convert to number."))
45        }
46      }else{
47        Err(RedisProtocolError::new_parse("Cannot convert array to number."))
48      }
49      $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
50    }
51  }
52);
53
54macro_rules! to_unsigned_number(
55  ($f:tt, $t:ty, $v:expr) => {
56    match $v {
57      $f::Error(s) => s.parse::<$t>().map_err(|e| e.into()),
58      $f::Integer(i) => if i >= 0 {
59        Ok(i as $t)
60      }else{
61        Err(RedisProtocolError::new_parse("Cannot convert from negative number"))
62      },
63      $f::SimpleString(s) | $f::BulkString(s) => str::from_utf8(&s)
64        .map_err(RedisProtocolError::from)
65        .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
66      $f::Array(mut a) => if a.len() == 1 {
67        match a.pop().unwrap() {
68          $f::Error(s) => s.parse::<$t>().map_err(|e| e.into()),
69          $f::Integer(i) => if i >= 0 {
70            Ok(i as $t)
71          }else{
72            Err(RedisProtocolError::new_parse("Cannot convert from negative number"))
73          },
74          $f::SimpleString(s) | $f::BulkString(s) => str::from_utf8(&s)
75            .map_err(RedisProtocolError::from)
76            .and_then(|s| s.parse::<$t>().map_err(RedisProtocolError::from)),
77          $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
78          _ => Err(RedisProtocolError::new_parse("Cannot convert to number."))
79        }
80      }else{
81        Err(RedisProtocolError::new_parse("Cannot convert array to number."))
82      }
83      $f::Null => Err(RedisProtocolError::new_parse("Cannot convert nil to number.")),
84    }
85  }
86);
87
88macro_rules! impl_signed_number (
89  ($t:ty) => {
90    impl FromResp2<OwnedFrame> for $t {
91      fn from_frame(value: OwnedFrame) -> Result<$t, RedisProtocolError> {
92        check_single_vec_reply!(value);
93        to_signed_number!(OwnedFrame, $t, value)
94      }
95    }
96
97    #[cfg(feature = "bytes")]
98    #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
99    impl FromResp2<BytesFrame> for $t {
100      fn from_frame(value: BytesFrame) -> Result<$t, RedisProtocolError> {
101        check_single_vec_reply!(value);
102        to_signed_number!(BytesFrame, $t, value)
103      }
104    }
105  }
106);
107
108macro_rules! impl_unsigned_number (
109  ($t:ty) => {
110    impl FromResp2<OwnedFrame> for $t {
111      fn from_frame(value: OwnedFrame) -> Result<$t, RedisProtocolError> {
112        check_single_vec_reply!(value);
113        to_unsigned_number!(OwnedFrame, $t, value)
114      }
115    }
116
117    #[cfg(feature = "bytes")]
118    #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
119    impl FromResp2<BytesFrame> for $t {
120      fn from_frame(value: BytesFrame) -> Result<$t, RedisProtocolError> {
121        check_single_vec_reply!(value);
122        to_unsigned_number!(BytesFrame, $t, value)
123      }
124    }
125  }
126);
127
128/// A trait used to convert frames into various other types.
129pub trait FromResp2<F: Resp2Frame>: Sized {
130  /// Convert a frame to the destination type.
131  fn from_frame(frame: F) -> Result<Self, RedisProtocolError>;
132
133  /// Convert multiple frames to the destination type.
134  fn from_frames(frames: Vec<F>) -> Result<Vec<Self>, RedisProtocolError> {
135    frames.into_iter().map(Self::from_frame).collect()
136  }
137
138  // Optional functions that can be used to specialize converting into certain types. Currently, we want to specialize
139  // for `Vec<u8>` and tuples.
140
141  #[doc(hidden)]
142  fn is_tuple() -> bool {
143    false
144  }
145
146  #[doc(hidden)]
147  fn from_owned_bytes(_: Vec<u8>) -> Option<Vec<Self>> {
148    None
149  }
150}
151
152impl_signed_number!(i8);
153impl_signed_number!(i16);
154impl_signed_number!(i32);
155impl_signed_number!(i64);
156impl_signed_number!(i128);
157impl_signed_number!(isize);
158
159impl FromResp2<OwnedFrame> for u8 {
160  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
161    check_single_vec_reply!(frame);
162    to_unsigned_number!(OwnedFrame, u8, frame)
163  }
164
165  fn from_owned_bytes(d: Vec<u8>) -> Option<Vec<Self>> {
166    Some(d)
167  }
168}
169#[cfg(feature = "bytes")]
170#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
171impl FromResp2<BytesFrame> for u8 {
172  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
173    check_single_vec_reply!(frame);
174    to_unsigned_number!(BytesFrame, u8, frame)
175  }
176
177  fn from_owned_bytes(d: Vec<u8>) -> Option<Vec<Self>> {
178    Some(d)
179  }
180}
181
182impl_unsigned_number!(u16);
183impl_unsigned_number!(u32);
184impl_unsigned_number!(u64);
185impl_unsigned_number!(u128);
186impl_unsigned_number!(usize);
187
188impl FromResp2<OwnedFrame> for f64 {
189  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
190    check_single_vec_reply!(frame);
191
192    frame
193      .as_f64()
194      .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
195  }
196}
197#[cfg(feature = "bytes")]
198#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
199impl FromResp2<BytesFrame> for f64 {
200  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
201    check_single_vec_reply!(frame);
202
203    frame
204      .as_f64()
205      .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
206  }
207}
208
209impl FromResp2<OwnedFrame> for f32 {
210  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
211    check_single_vec_reply!(frame);
212
213    frame
214      .as_f64()
215      .map(|f| f as f32)
216      .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
217  }
218}
219#[cfg(feature = "bytes")]
220#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
221impl FromResp2<BytesFrame> for f32 {
222  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
223    check_single_vec_reply!(frame);
224
225    frame
226      .as_f64()
227      .map(|f| f as f32)
228      .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to f64"))
229  }
230}
231
232impl FromResp2<OwnedFrame> for bool {
233  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
234    check_single_vec_reply!(frame);
235
236    frame
237      .as_bool()
238      .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to bool"))
239  }
240}
241#[cfg(feature = "bytes")]
242#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
243impl FromResp2<BytesFrame> for bool {
244  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
245    check_single_vec_reply!(frame);
246
247    frame
248      .as_bool()
249      .ok_or_else(|| RedisProtocolError::new_parse("Cannot convert to bool"))
250  }
251}
252
253impl FromResp2<OwnedFrame> for () {
254  fn from_frame(_: OwnedFrame) -> Result<Self, RedisProtocolError> {
255    Ok(())
256  }
257}
258#[cfg(feature = "bytes")]
259#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
260impl FromResp2<BytesFrame> for () {
261  fn from_frame(_: BytesFrame) -> Result<Self, RedisProtocolError> {
262    Ok(())
263  }
264}
265
266impl FromResp2<OwnedFrame> for OwnedFrame {
267  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
268    Ok(frame)
269  }
270}
271#[cfg(feature = "bytes")]
272#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
273impl FromResp2<BytesFrame> for BytesFrame {
274  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
275    Ok(frame)
276  }
277}
278
279impl FromResp2<OwnedFrame> for String {
280  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
281    debug_type!("FromResp2(String): {:?}", frame);
282    check_single_vec_reply!(frame);
283
284    Ok(match frame {
285      OwnedFrame::BulkString(b) | OwnedFrame::SimpleString(b) => String::from_utf8(b)?,
286      OwnedFrame::Error(s) => s,
287      OwnedFrame::Integer(i) => i.to_string(),
288      _ => return Err(RedisProtocolError::new_parse("Cannot convert to string.")),
289    })
290  }
291}
292#[cfg(feature = "bytes")]
293#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
294impl FromResp2<BytesFrame> for String {
295  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
296    debug_type!("FromResp2(String): {:?}", frame);
297    check_single_vec_reply!(frame);
298
299    Ok(match frame {
300      BytesFrame::BulkString(b) | BytesFrame::SimpleString(b) => String::from_utf8(b.to_vec())?,
301      BytesFrame::Error(s) => s.to_string(),
302      BytesFrame::Integer(i) => i.to_string(),
303      _ => return Err(RedisProtocolError::new_parse("Cannot convert to string.")),
304    })
305  }
306}
307
308#[cfg(feature = "bytes")]
309#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
310impl FromResp2<BytesFrame> for Str {
311  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
312    debug_type!("FromResp2(Str): {:?}", frame);
313    check_single_vec_reply!(frame);
314
315    Ok(match frame {
316      BytesFrame::BulkString(b) | BytesFrame::SimpleString(b) => Str::from_inner(b)?,
317      BytesFrame::Error(s) => s,
318      BytesFrame::Integer(i) => i.to_string().into(),
319      _ => return Err(RedisProtocolError::new_parse("Cannot convert to string.")),
320    })
321  }
322}
323
324#[cfg(feature = "bytes")]
325#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
326impl FromResp2<BytesFrame> for Bytes {
327  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
328    debug_type!("FromResp2(Bytes): {:?}", frame);
329    check_single_vec_reply!(frame);
330
331    Ok(match frame {
332      BytesFrame::BulkString(b) | BytesFrame::SimpleString(b) => b,
333      BytesFrame::Error(s) => s.into_inner(),
334      BytesFrame::Integer(i) => i.to_string().into(),
335      _ => return Err(RedisProtocolError::new_parse("Cannot convert to bytes.")),
336    })
337  }
338}
339
340impl<T> FromResp2<OwnedFrame> for Option<T>
341where
342  T: FromResp2<OwnedFrame>,
343{
344  fn from_frame(frame: OwnedFrame) -> Result<Option<T>, RedisProtocolError> {
345    debug_type!("FromResp2(Option<{}>): {:?}", std::any::type_name::<T>(), frame);
346
347    match frame {
348      OwnedFrame::Array(inner) => {
349        if inner.is_empty() {
350          Ok(None)
351        } else {
352          T::from_frame(OwnedFrame::Array(inner)).map(Some)
353        }
354      },
355      OwnedFrame::Null => Ok(None),
356      _ => T::from_frame(frame).map(Some),
357    }
358  }
359}
360#[cfg(feature = "bytes")]
361#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
362impl<T> FromResp2<BytesFrame> for Option<T>
363where
364  T: FromResp2<BytesFrame>,
365{
366  fn from_frame(frame: BytesFrame) -> Result<Option<T>, RedisProtocolError> {
367    debug_type!("FromResp2(Option<{}>): {:?}", std::any::type_name::<T>(), frame);
368
369    match frame {
370      BytesFrame::Array(inner) => {
371        if inner.is_empty() {
372          Ok(None)
373        } else {
374          T::from_frame(BytesFrame::Array(inner)).map(Some)
375        }
376      },
377      BytesFrame::Null => Ok(None),
378      _ => T::from_frame(frame).map(Some),
379    }
380  }
381}
382
383impl<T> FromResp2<OwnedFrame> for Vec<T>
384where
385  T: FromResp2<OwnedFrame>,
386{
387  fn from_frame(frame: OwnedFrame) -> Result<Vec<T>, RedisProtocolError> {
388    debug_type!("FromResp2(Vec<{}>): {:?}", std::any::type_name::<T>(), frame);
389
390    match frame {
391      OwnedFrame::BulkString(buf) => {
392        // hacky way to check if T is bytes without consuming `string`
393        if T::from_owned_bytes(Vec::new()).is_some() {
394          T::from_owned_bytes(buf).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
395        } else {
396          Ok(vec![T::from_frame(OwnedFrame::BulkString(buf))?])
397        }
398      },
399      OwnedFrame::SimpleString(buf) => {
400        if T::from_owned_bytes(Vec::new()).is_some() {
401          T::from_owned_bytes(buf).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
402        } else {
403          Ok(vec![T::from_frame(OwnedFrame::SimpleString(buf))?])
404        }
405      },
406      OwnedFrame::Error(buf) => {
407        if T::from_owned_bytes(Vec::new()).is_some() {
408          T::from_owned_bytes(buf.into_bytes()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
409        } else {
410          Ok(vec![T::from_frame(OwnedFrame::Error(buf))?])
411        }
412      },
413      OwnedFrame::Array(values) => {
414        if !values.is_empty() {
415          if let OwnedFrame::Array(_) = &values[0] {
416            values.into_iter().map(|x| T::from_frame(x)).collect()
417          } else {
418            T::from_frames(values)
419          }
420        } else {
421          Ok(Vec::new())
422        }
423      },
424      OwnedFrame::Integer(i) => Ok(vec![T::from_frame(OwnedFrame::Integer(i))?]),
425      OwnedFrame::Null => Ok(Vec::new()),
426    }
427  }
428}
429
430#[cfg(feature = "bytes")]
431#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
432impl<T> FromResp2<BytesFrame> for Vec<T>
433where
434  T: FromResp2<BytesFrame>,
435{
436  fn from_frame(frame: BytesFrame) -> Result<Vec<T>, RedisProtocolError> {
437    debug_type!("FromResp2(Vec<{}>): {:?}", std::any::type_name::<T>(), frame);
438
439    match frame {
440      BytesFrame::BulkString(buf) => {
441        if T::from_owned_bytes(Vec::new()).is_some() {
442          T::from_owned_bytes(buf.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
443        } else {
444          Ok(vec![T::from_frame(BytesFrame::BulkString(buf))?])
445        }
446      },
447      BytesFrame::SimpleString(buf) => {
448        if T::from_owned_bytes(Vec::new()).is_some() {
449          T::from_owned_bytes(buf.to_vec()).ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
450        } else {
451          Ok(vec![T::from_frame(BytesFrame::SimpleString(buf))?])
452        }
453      },
454      BytesFrame::Error(buf) => {
455        if T::from_owned_bytes(Vec::new()).is_some() {
456          T::from_owned_bytes(buf.into_inner().to_vec())
457            .ok_or(RedisProtocolError::new_parse("Could not convert to bytes."))
458        } else {
459          Ok(vec![T::from_frame(BytesFrame::Error(buf))?])
460        }
461      },
462      BytesFrame::Array(values) => {
463        if !values.is_empty() {
464          if let BytesFrame::Array(_) = &values[0] {
465            values.into_iter().map(|x| T::from_frame(x)).collect()
466          } else {
467            T::from_frames(values)
468          }
469        } else {
470          Ok(Vec::new())
471        }
472      },
473      BytesFrame::Integer(i) => Ok(vec![T::from_frame(BytesFrame::Integer(i))?]),
474      BytesFrame::Null => Ok(Vec::new()),
475    }
476  }
477}
478
479impl<T, const N: usize> FromResp2<OwnedFrame> for [T; N]
480where
481  T: FromResp2<OwnedFrame>,
482{
483  fn from_frame(value: OwnedFrame) -> Result<[T; N], RedisProtocolError> {
484    debug_type!("FromResp2([{}; {}]): {:?}", std::any::type_name::<T>(), N, value);
485    // use the `from_value` impl for Vec<T>
486    let value: Vec<T> = value.convert()?;
487    let len = value.len();
488
489    value.try_into().map_err(|_| {
490      RedisProtocolError::new_parse(format!("Failed to convert to array. Expected {}, found {}.", N, len))
491    })
492  }
493}
494
495#[cfg(feature = "bytes")]
496#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
497impl<T, const N: usize> FromResp2<BytesFrame> for [T; N]
498where
499  T: FromResp2<BytesFrame>,
500{
501  fn from_frame(value: BytesFrame) -> Result<[T; N], RedisProtocolError> {
502    debug_type!("FromResp2([{}; {}]): {:?}", std::any::type_name::<T>(), N, value);
503    // use the `from_value` impl for Vec<T>
504    let value: Vec<T> = value.convert()?;
505    let len = value.len();
506
507    value.try_into().map_err(|_| {
508      RedisProtocolError::new_parse(format!("Failed to convert to array. Expected {}, found {}.", N, len))
509    })
510  }
511}
512
513impl<K, V, S> FromResp2<OwnedFrame> for HashMap<K, V, S>
514where
515  K: FromResp2<OwnedFrame> + Eq + Hash,
516  V: FromResp2<OwnedFrame>,
517  S: BuildHasher + Default,
518{
519  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
520    debug_type!(
521      "FromResp2(HashMap<{}, {}>): {:?}",
522      std::any::type_name::<K>(),
523      std::any::type_name::<V>(),
524      frame
525    );
526
527    if let OwnedFrame::Array(mut values) = frame {
528      if values.is_empty() {
529        return Ok::<HashMap<K, V, S>, _>(HashMap::default());
530      }
531
532      if values.len() % 2 == 0 {
533        let mut out = HashMap::default();
534        out.reserve(values.len() / 2);
535
536        #[allow(clippy::manual_while_let_some)]
537        while !values.is_empty() {
538          let value = values.pop().unwrap();
539          let key = values.pop().unwrap();
540
541          out.insert(K::from_frame(key)?, V::from_frame(value)?);
542        }
543        Ok(out)
544      } else {
545        Err(RedisProtocolError::new_parse("Expected even number of elements"))
546      }
547    } else {
548      Err(RedisProtocolError::new_parse("Cannot convert to map"))
549    }
550  }
551}
552
553#[cfg(feature = "bytes")]
554#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
555impl<K, V, S> FromResp2<BytesFrame> for HashMap<K, V, S>
556where
557  K: FromResp2<BytesFrame> + Eq + Hash,
558  V: FromResp2<BytesFrame>,
559  S: BuildHasher + Default,
560{
561  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
562    debug_type!(
563      "FromResp2(HashMap<{}, {}>): {:?}",
564      std::any::type_name::<K>(),
565      std::any::type_name::<V>(),
566      frame
567    );
568
569    if let BytesFrame::Array(mut values) = frame {
570      if values.is_empty() {
571        return Ok::<HashMap<K, V, S>, _>(HashMap::default());
572      }
573
574      if values.len() % 2 == 0 {
575        let mut out = HashMap::default();
576        out.reserve(values.len() / 2);
577
578        #[allow(clippy::manual_while_let_some)]
579        while !values.is_empty() {
580          let value = values.pop().unwrap();
581          let key = values.pop().unwrap();
582
583          out.insert(K::from_frame(key)?, V::from_frame(value)?);
584        }
585        Ok(out)
586      } else {
587        Err(RedisProtocolError::new_parse("Expected even number of elements"))
588      }
589    } else {
590      Err(RedisProtocolError::new_parse("Cannot convert to map"))
591    }
592  }
593}
594
595impl<V, S> FromResp2<OwnedFrame> for HashSet<V, S>
596where
597  V: FromResp2<OwnedFrame> + Hash + Eq,
598  S: BuildHasher + Default,
599{
600  fn from_frame(frame: OwnedFrame) -> Result<Self, RedisProtocolError> {
601    debug_type!("FromResp2(HashSet<{}>): {:?}", std::any::type_name::<V>(), frame);
602
603    if let OwnedFrame::Array(values) = frame {
604      values.into_iter().map(V::from_frame).collect()
605    } else {
606      Err(RedisProtocolError::new_parse("Cannot convert to set"))
607    }
608  }
609}
610
611#[cfg(feature = "bytes")]
612#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
613impl<V, S> FromResp2<BytesFrame> for HashSet<V, S>
614where
615  V: FromResp2<BytesFrame> + Hash + Eq,
616  S: BuildHasher + Default,
617{
618  fn from_frame(frame: BytesFrame) -> Result<Self, RedisProtocolError> {
619    debug_type!("FromResp2(HashSet<{}>): {:?}", std::any::type_name::<V>(), frame);
620
621    if let BytesFrame::Array(values) = frame {
622      values.into_iter().map(V::from_frame).collect()
623    } else {
624      Err(RedisProtocolError::new_parse("Cannot convert to set"))
625    }
626  }
627}
628
629macro_rules! impl_from_resp2_tuple {
630  () => ();
631  ($($name:ident,)+) => (
632    #[doc(hidden)]
633    #[cfg(feature = "bytes")]
634    impl<$($name: FromResp2<BytesFrame>),*> FromResp2<BytesFrame> for ($($name,)*) {
635      fn is_tuple() -> bool {
636        true
637      }
638
639      #[allow(non_snake_case, unused_variables)]
640      fn from_frame(v: BytesFrame) -> Result<($($name,)*), RedisProtocolError> {
641        if let BytesFrame::Array(mut values) = v {
642          let mut n = 0;
643          $(let $name = (); n += 1;)*
644          debug_type!("FromResp2({}-tuple): {:?}", n, values);
645          if values.len() != n {
646            return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
647          }
648
649          values.reverse();
650          Ok(($({let $name = (); values
651            .pop()
652            .ok_or(RedisProtocolError::new_parse("Expected value, found none."))?
653            .convert()?
654          },)*))
655        }else{
656          Err(RedisProtocolError::new_parse("Could not convert to tuple."))
657        }
658      }
659
660      #[allow(non_snake_case, unused_variables)]
661      fn from_frames(mut values: Vec<BytesFrame>) -> Result<Vec<($($name,)*)>, RedisProtocolError> {
662        let mut n = 0;
663        $(let $name = (); n += 1;)*
664        debug_type!("FromResp2({}-tuple): {:?}", n, values);
665        if values.len() % n != 0 {
666          return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
667        }
668
669        let mut out = Vec::with_capacity(values.len() / n);
670        // this would be cleaner if there were an owned `chunks` variant
671        for chunk in values.chunks_exact_mut(n) {
672          match chunk {
673            [$($name),*] => out.push(($($name.take().convert()?),*),),
674             _ => unreachable!(),
675          }
676        }
677
678        Ok(out)
679      }
680    }
681
682    #[doc(hidden)]
683    impl<$($name: FromResp2<OwnedFrame>),*> FromResp2<OwnedFrame> for ($($name,)*) {
684      fn is_tuple() -> bool {
685        true
686      }
687
688      #[allow(non_snake_case, unused_variables)]
689      fn from_frame(v: OwnedFrame) -> Result<($($name,)*), RedisProtocolError> {
690        if let OwnedFrame::Array(mut values) = v {
691          let mut n = 0;
692          $(let $name = (); n += 1;)*
693          debug_type!("FromResp2({}-tuple): {:?}", n, values);
694          if values.len() != n {
695            return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
696          }
697
698          values.reverse();
699          Ok(($({let $name = (); values
700            .pop()
701            .ok_or(RedisProtocolError::new_parse("Expected value, found none."))?
702            .convert()?
703          },)*))
704        }else{
705          Err(RedisProtocolError::new_parse("Could not convert to tuple."))
706        }
707      }
708
709      #[allow(non_snake_case, unused_variables)]
710      fn from_frames(mut values: Vec<OwnedFrame>) -> Result<Vec<($($name,)*)>, RedisProtocolError> {
711        let mut n = 0;
712        $(let $name = (); n += 1;)*
713        debug_type!("FromResp2({}-tuple): {:?}", n, values);
714        if values.len() % n != 0 {
715          return Err(RedisProtocolError::new_parse(format!("Invalid tuple dimension. Expected {}, found {}.", n, values.len())));
716        }
717
718        let mut out = Vec::with_capacity(values.len() / n);
719        // this would be cleaner if there were an owned `chunks` variant
720        for chunk in values.chunks_exact_mut(n) {
721          match chunk {
722            [$($name),*] => out.push(($($name.take().convert()?),*),),
723             _ => unreachable!(),
724          }
725        }
726
727        Ok(out)
728      }
729    }
730    impl_from_resp2_peel!($($name,)*);
731  )
732}
733
734macro_rules! impl_from_resp2_peel {
735  ($name:ident, $($other:ident,)*) => (impl_from_resp2_tuple!($($other,)*);)
736}
737
738impl_from_resp2_tuple! { T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, }
739
740// Regression tests duplicated for each frame type.
741#[cfg(test)]
742mod owned_tests {
743  use super::*;
744
745  #[test]
746  fn should_convert_signed_numeric_types() {
747    let _foo: i8 = OwnedFrame::BulkString("123".into()).convert().unwrap();
748    assert_eq!(_foo, 123);
749    let _foo: i8 = OwnedFrame::Integer(123).convert().unwrap();
750    assert_eq!(_foo, 123);
751    let _foo: i16 = OwnedFrame::BulkString("123".into()).convert().unwrap();
752    assert_eq!(_foo, 123);
753    let _foo: i16 = OwnedFrame::Integer(123).convert().unwrap();
754    assert_eq!(_foo, 123);
755    let _foo: i32 = OwnedFrame::BulkString("123".into()).convert().unwrap();
756    assert_eq!(_foo, 123);
757    let _foo: i32 = OwnedFrame::Integer(123).convert().unwrap();
758    assert_eq!(_foo, 123);
759    let _foo: i64 = OwnedFrame::BulkString("123".into()).convert().unwrap();
760    assert_eq!(_foo, 123);
761    let _foo: i64 = OwnedFrame::Integer(123).convert().unwrap();
762    assert_eq!(_foo, 123);
763    let _foo: i128 = OwnedFrame::BulkString("123".into()).convert().unwrap();
764    assert_eq!(_foo, 123);
765    let _foo: i128 = OwnedFrame::Integer(123).convert().unwrap();
766    assert_eq!(_foo, 123);
767    let _foo: isize = OwnedFrame::BulkString("123".into()).convert().unwrap();
768    assert_eq!(_foo, 123);
769    let _foo: isize = OwnedFrame::Integer(123).convert().unwrap();
770    assert_eq!(_foo, 123);
771    let _foo: f32 = OwnedFrame::BulkString("123.5".into()).convert().unwrap();
772    assert_eq!(_foo, 123.5);
773    let _foo: f64 = OwnedFrame::BulkString("123.5".into()).convert().unwrap();
774    assert_eq!(_foo, 123.5);
775  }
776
777  #[test]
778  fn should_convert_unsigned_numeric_types() {
779    let _foo: u8 = OwnedFrame::BulkString("123".into()).convert().unwrap();
780    assert_eq!(_foo, 123);
781    let _foo: u8 = OwnedFrame::Integer(123).convert().unwrap();
782    assert_eq!(_foo, 123);
783    let _foo: u16 = OwnedFrame::BulkString("123".into()).convert().unwrap();
784    assert_eq!(_foo, 123);
785    let _foo: u16 = OwnedFrame::Integer(123).convert().unwrap();
786    assert_eq!(_foo, 123);
787    let _foo: u32 = OwnedFrame::BulkString("123".into()).convert().unwrap();
788    assert_eq!(_foo, 123);
789    let _foo: u32 = OwnedFrame::Integer(123).convert().unwrap();
790    assert_eq!(_foo, 123);
791    let _foo: u64 = OwnedFrame::BulkString("123".into()).convert().unwrap();
792    assert_eq!(_foo, 123);
793    let _foo: u64 = OwnedFrame::Integer(123).convert().unwrap();
794    assert_eq!(_foo, 123);
795    let _foo: u128 = OwnedFrame::BulkString("123".into()).convert().unwrap();
796    assert_eq!(_foo, 123);
797    let _foo: u128 = OwnedFrame::Integer(123).convert().unwrap();
798    assert_eq!(_foo, 123);
799    let _foo: usize = OwnedFrame::BulkString("123".into()).convert().unwrap();
800    assert_eq!(_foo, 123);
801    let _foo: usize = OwnedFrame::Integer(123).convert().unwrap();
802    assert_eq!(_foo, 123);
803  }
804
805  #[test]
806  fn should_return_not_found_with_null_number_types() {
807    let result: Result<u8, _> = OwnedFrame::Null.convert();
808    assert!(result.is_err());
809    let result: Result<u16, _> = OwnedFrame::Null.convert();
810    assert!(result.is_err());
811    let result: Result<u32, _> = OwnedFrame::Null.convert();
812    assert!(result.is_err());
813    let result: Result<u64, _> = OwnedFrame::Null.convert();
814    assert!(result.is_err());
815    let result: Result<u128, _> = OwnedFrame::Null.convert();
816    assert!(result.is_err());
817    let result: Result<usize, _> = OwnedFrame::Null.convert();
818    assert!(result.is_err());
819    let result: Result<i8, _> = OwnedFrame::Null.convert();
820    assert!(result.is_err());
821    let result: Result<i16, _> = OwnedFrame::Null.convert();
822    assert!(result.is_err());
823    let result: Result<i32, _> = OwnedFrame::Null.convert();
824    assert!(result.is_err());
825    let result: Result<i64, _> = OwnedFrame::Null.convert();
826    assert!(result.is_err());
827    let result: Result<i128, _> = OwnedFrame::Null.convert();
828    assert!(result.is_err());
829    let result: Result<isize, _> = OwnedFrame::Null.convert();
830    assert!(result.is_err());
831  }
832
833  #[test]
834  fn should_convert_strings() {
835    let _foo: String = OwnedFrame::BulkString("foo".into()).convert().unwrap();
836    assert_eq!(_foo, "foo".to_owned());
837  }
838
839  #[test]
840  fn should_convert_numbers_to_bools() {
841    let foo: bool = OwnedFrame::Integer(0).convert().unwrap();
842    assert!(!foo);
843    let foo: bool = OwnedFrame::Integer(1).convert().unwrap();
844    assert!(foo);
845    let foo: bool = OwnedFrame::BulkString("0".into()).convert().unwrap();
846    assert!(!foo);
847    let foo: bool = OwnedFrame::BulkString("1".into()).convert().unwrap();
848    assert!(foo);
849  }
850
851  #[test]
852  fn should_convert_bytes() {
853    let foo: Vec<u8> = OwnedFrame::BulkString("foo".as_bytes().to_vec()).convert().unwrap();
854    assert_eq!(foo, "foo".as_bytes().to_vec());
855    let foo: Vec<u8> = OwnedFrame::BulkString("foo".into()).convert().unwrap();
856    assert_eq!(foo, "foo".as_bytes().to_vec());
857    let foo: Vec<u8> = OwnedFrame::Array(vec![
858      OwnedFrame::Integer(102),
859      OwnedFrame::Integer(111),
860      OwnedFrame::Integer(111),
861    ])
862    .convert()
863    .unwrap();
864    assert_eq!(foo, "foo".as_bytes().to_vec());
865  }
866
867  #[test]
868  fn should_convert_arrays() {
869    let foo: Vec<String> = OwnedFrame::Array(vec![
870      OwnedFrame::SimpleString("a".into()),
871      OwnedFrame::SimpleString("b".into()),
872    ])
873    .convert()
874    .unwrap();
875    assert_eq!(foo, vec!["a".to_owned(), "b".to_owned()]);
876  }
877
878  #[test]
879  fn should_convert_hash_maps() {
880    let foo: HashMap<String, u16> = OwnedFrame::Array(vec![
881      OwnedFrame::SimpleString("a".into()),
882      OwnedFrame::Integer(1),
883      OwnedFrame::SimpleString("b".into()),
884      OwnedFrame::Integer(2),
885    ])
886    .convert()
887    .unwrap();
888
889    let mut expected = HashMap::new();
890    expected.insert("a".to_owned(), 1);
891    expected.insert("b".to_owned(), 2);
892    assert_eq!(foo, expected);
893  }
894
895  #[test]
896  fn should_convert_hash_sets() {
897    let foo: HashSet<String> = OwnedFrame::Array(vec![
898      OwnedFrame::SimpleString("a".into()),
899      OwnedFrame::SimpleString("b".into()),
900    ])
901    .convert()
902    .unwrap();
903
904    let mut expected = HashSet::new();
905    expected.insert("a".to_owned());
906    expected.insert("b".to_owned());
907    assert_eq!(foo, expected);
908  }
909
910  #[test]
911  fn should_convert_tuples() {
912    let foo: (String, i64) = OwnedFrame::Array(vec![OwnedFrame::SimpleString("a".into()), OwnedFrame::Integer(1)])
913      .convert()
914      .unwrap();
915    assert_eq!(foo, ("a".to_owned(), 1));
916  }
917
918  #[test]
919  fn should_convert_array_tuples() {
920    let foo: Vec<(String, i64)> = OwnedFrame::Array(vec![
921      OwnedFrame::SimpleString("a".into()),
922      OwnedFrame::Integer(1),
923      OwnedFrame::SimpleString("b".into()),
924      OwnedFrame::Integer(2),
925    ])
926    .convert()
927    .unwrap();
928    assert_eq!(foo, vec![("a".to_owned(), 1), ("b".to_owned(), 2)]);
929  }
930
931  #[test]
932  fn should_handle_single_element_vector_to_scalar() {
933    assert!(OwnedFrame::Array(vec![]).convert::<String>().is_err());
934    assert_eq!(
935      OwnedFrame::Array(vec![OwnedFrame::SimpleString("foo".into())]).convert::<String>(),
936      Ok("foo".into())
937    );
938    assert!(OwnedFrame::Array(vec![
939      OwnedFrame::SimpleString("foo".into()),
940      OwnedFrame::SimpleString("bar".into())
941    ])
942    .convert::<String>()
943    .is_err());
944
945    assert_eq!(OwnedFrame::Array(vec![]).convert::<Option<String>>(), Ok(None));
946    assert_eq!(
947      OwnedFrame::Array(vec![OwnedFrame::SimpleString("foo".into())]).convert::<Option<String>>(),
948      Ok(Some("foo".into()))
949    );
950    assert!(OwnedFrame::Array(vec![
951      OwnedFrame::SimpleString("foo".into()),
952      OwnedFrame::SimpleString("bar".into())
953    ])
954    .convert::<Option<String>>()
955    .is_err());
956  }
957
958  #[test]
959  fn should_convert_null_to_empty_array() {
960    assert_eq!(Vec::<String>::new(), OwnedFrame::Null.convert::<Vec<String>>().unwrap());
961    assert_eq!(Vec::<u8>::new(), OwnedFrame::Null.convert::<Vec<u8>>().unwrap());
962  }
963
964  #[test]
965  fn should_convert_to_fixed_arrays() {
966    let foo: [i64; 2] = OwnedFrame::Array(vec![OwnedFrame::Integer(1), OwnedFrame::Integer(2)])
967      .convert()
968      .unwrap();
969    assert_eq!(foo, [1, 2]);
970
971    assert!(OwnedFrame::Array(vec![OwnedFrame::Integer(1), OwnedFrame::Integer(2)])
972      .convert::<[i64; 3]>()
973      .is_err());
974    assert!(OwnedFrame::Array(vec![]).convert::<[i64; 3]>().is_err());
975  }
976}
977
978#[cfg(test)]
979#[cfg(feature = "bytes")]
980mod bytes_tests {
981  use super::*;
982
983  #[test]
984  fn should_convert_signed_numeric_types() {
985    let _foo: i8 = BytesFrame::BulkString("123".into()).convert().unwrap();
986    assert_eq!(_foo, 123);
987    let _foo: i8 = BytesFrame::Integer(123).convert().unwrap();
988    assert_eq!(_foo, 123);
989    let _foo: i16 = BytesFrame::BulkString("123".into()).convert().unwrap();
990    assert_eq!(_foo, 123);
991    let _foo: i16 = BytesFrame::Integer(123).convert().unwrap();
992    assert_eq!(_foo, 123);
993    let _foo: i32 = BytesFrame::BulkString("123".into()).convert().unwrap();
994    assert_eq!(_foo, 123);
995    let _foo: i32 = BytesFrame::Integer(123).convert().unwrap();
996    assert_eq!(_foo, 123);
997    let _foo: i64 = BytesFrame::BulkString("123".into()).convert().unwrap();
998    assert_eq!(_foo, 123);
999    let _foo: i64 = BytesFrame::Integer(123).convert().unwrap();
1000    assert_eq!(_foo, 123);
1001    let _foo: i128 = BytesFrame::BulkString("123".into()).convert().unwrap();
1002    assert_eq!(_foo, 123);
1003    let _foo: i128 = BytesFrame::Integer(123).convert().unwrap();
1004    assert_eq!(_foo, 123);
1005    let _foo: isize = BytesFrame::BulkString("123".into()).convert().unwrap();
1006    assert_eq!(_foo, 123);
1007    let _foo: isize = BytesFrame::Integer(123).convert().unwrap();
1008    assert_eq!(_foo, 123);
1009    let _foo: f32 = BytesFrame::BulkString("123.5".into()).convert().unwrap();
1010    assert_eq!(_foo, 123.5);
1011    let _foo: f64 = BytesFrame::BulkString("123.5".into()).convert().unwrap();
1012    assert_eq!(_foo, 123.5);
1013  }
1014
1015  #[test]
1016  fn should_convert_unsigned_numeric_types() {
1017    let _foo: u8 = BytesFrame::BulkString("123".into()).convert().unwrap();
1018    assert_eq!(_foo, 123);
1019    let _foo: u8 = BytesFrame::Integer(123).convert().unwrap();
1020    assert_eq!(_foo, 123);
1021    let _foo: u16 = BytesFrame::BulkString("123".into()).convert().unwrap();
1022    assert_eq!(_foo, 123);
1023    let _foo: u16 = BytesFrame::Integer(123).convert().unwrap();
1024    assert_eq!(_foo, 123);
1025    let _foo: u32 = BytesFrame::BulkString("123".into()).convert().unwrap();
1026    assert_eq!(_foo, 123);
1027    let _foo: u32 = BytesFrame::Integer(123).convert().unwrap();
1028    assert_eq!(_foo, 123);
1029    let _foo: u64 = BytesFrame::BulkString("123".into()).convert().unwrap();
1030    assert_eq!(_foo, 123);
1031    let _foo: u64 = BytesFrame::Integer(123).convert().unwrap();
1032    assert_eq!(_foo, 123);
1033    let _foo: u128 = BytesFrame::BulkString("123".into()).convert().unwrap();
1034    assert_eq!(_foo, 123);
1035    let _foo: u128 = BytesFrame::Integer(123).convert().unwrap();
1036    assert_eq!(_foo, 123);
1037    let _foo: usize = BytesFrame::BulkString("123".into()).convert().unwrap();
1038    assert_eq!(_foo, 123);
1039    let _foo: usize = BytesFrame::Integer(123).convert().unwrap();
1040    assert_eq!(_foo, 123);
1041  }
1042
1043  #[test]
1044  fn should_return_not_found_with_null_number_types() {
1045    let result: Result<u8, _> = BytesFrame::Null.convert();
1046    assert!(result.is_err());
1047    let result: Result<u16, _> = BytesFrame::Null.convert();
1048    assert!(result.is_err());
1049    let result: Result<u32, _> = BytesFrame::Null.convert();
1050    assert!(result.is_err());
1051    let result: Result<u64, _> = BytesFrame::Null.convert();
1052    assert!(result.is_err());
1053    let result: Result<u128, _> = BytesFrame::Null.convert();
1054    assert!(result.is_err());
1055    let result: Result<usize, _> = BytesFrame::Null.convert();
1056    assert!(result.is_err());
1057    let result: Result<i8, _> = BytesFrame::Null.convert();
1058    assert!(result.is_err());
1059    let result: Result<i16, _> = BytesFrame::Null.convert();
1060    assert!(result.is_err());
1061    let result: Result<i32, _> = BytesFrame::Null.convert();
1062    assert!(result.is_err());
1063    let result: Result<i64, _> = BytesFrame::Null.convert();
1064    assert!(result.is_err());
1065    let result: Result<i128, _> = BytesFrame::Null.convert();
1066    assert!(result.is_err());
1067    let result: Result<isize, _> = BytesFrame::Null.convert();
1068    assert!(result.is_err());
1069  }
1070
1071  #[test]
1072  fn should_convert_strings() {
1073    let _foo: String = BytesFrame::BulkString("foo".into()).convert().unwrap();
1074    assert_eq!(_foo, "foo".to_owned());
1075  }
1076
1077  #[test]
1078  fn should_convert_numbers_to_bools() {
1079    let foo: bool = BytesFrame::Integer(0).convert().unwrap();
1080    assert!(!foo);
1081    let foo: bool = BytesFrame::Integer(1).convert().unwrap();
1082    assert!(foo);
1083    let foo: bool = BytesFrame::BulkString("0".into()).convert().unwrap();
1084    assert!(!foo);
1085    let foo: bool = BytesFrame::BulkString("1".into()).convert().unwrap();
1086    assert!(foo);
1087  }
1088
1089  #[test]
1090  fn should_convert_bytes() {
1091    let foo: Vec<u8> = BytesFrame::BulkString("foo".as_bytes().to_vec().into())
1092      .convert()
1093      .unwrap();
1094    assert_eq!(foo, "foo".as_bytes().to_vec());
1095    let foo: Vec<u8> = BytesFrame::BulkString("foo".into()).convert().unwrap();
1096    assert_eq!(foo, "foo".as_bytes().to_vec());
1097    let foo: Vec<u8> = BytesFrame::Array(vec![
1098      BytesFrame::Integer(102),
1099      BytesFrame::Integer(111),
1100      BytesFrame::Integer(111),
1101    ])
1102    .convert()
1103    .unwrap();
1104    assert_eq!(foo, "foo".as_bytes().to_vec());
1105  }
1106
1107  #[test]
1108  fn should_convert_arrays() {
1109    let foo: Vec<String> = BytesFrame::Array(vec![
1110      BytesFrame::SimpleString("a".into()),
1111      BytesFrame::SimpleString("b".into()),
1112    ])
1113    .convert()
1114    .unwrap();
1115    assert_eq!(foo, vec!["a".to_owned(), "b".to_owned()]);
1116  }
1117
1118  #[test]
1119  fn should_convert_hash_maps() {
1120    let foo: HashMap<String, u16> = BytesFrame::Array(vec![
1121      BytesFrame::SimpleString("a".into()),
1122      BytesFrame::Integer(1),
1123      BytesFrame::SimpleString("b".into()),
1124      BytesFrame::Integer(2),
1125    ])
1126    .convert()
1127    .unwrap();
1128
1129    let mut expected = HashMap::new();
1130    expected.insert("a".to_owned(), 1);
1131    expected.insert("b".to_owned(), 2);
1132    assert_eq!(foo, expected);
1133  }
1134
1135  #[test]
1136  fn should_convert_hash_sets() {
1137    let foo: HashSet<String> = BytesFrame::Array(vec![
1138      BytesFrame::SimpleString("a".into()),
1139      BytesFrame::SimpleString("b".into()),
1140    ])
1141    .convert()
1142    .unwrap();
1143
1144    let mut expected = HashSet::new();
1145    expected.insert("a".to_owned());
1146    expected.insert("b".to_owned());
1147    assert_eq!(foo, expected);
1148  }
1149
1150  #[test]
1151  fn should_convert_tuples() {
1152    let foo: (String, i64) = BytesFrame::Array(vec![BytesFrame::SimpleString("a".into()), BytesFrame::Integer(1)])
1153      .convert()
1154      .unwrap();
1155    assert_eq!(foo, ("a".to_owned(), 1));
1156  }
1157
1158  #[test]
1159  fn should_convert_array_tuples() {
1160    let foo: Vec<(String, i64)> = BytesFrame::Array(vec![
1161      BytesFrame::SimpleString("a".into()),
1162      BytesFrame::Integer(1),
1163      BytesFrame::SimpleString("b".into()),
1164      BytesFrame::Integer(2),
1165    ])
1166    .convert()
1167    .unwrap();
1168    assert_eq!(foo, vec![("a".to_owned(), 1), ("b".to_owned(), 2)]);
1169  }
1170
1171  #[test]
1172  fn should_handle_single_element_vector_to_scalar() {
1173    assert!(BytesFrame::Array(vec![]).convert::<String>().is_err());
1174    assert_eq!(
1175      BytesFrame::Array(vec![BytesFrame::SimpleString("foo".into())]).convert::<String>(),
1176      Ok("foo".into())
1177    );
1178    assert!(BytesFrame::Array(vec![
1179      BytesFrame::SimpleString("foo".into()),
1180      BytesFrame::SimpleString("bar".into())
1181    ])
1182    .convert::<String>()
1183    .is_err());
1184
1185    assert_eq!(BytesFrame::Array(vec![]).convert::<Option<String>>(), Ok(None));
1186    assert_eq!(
1187      BytesFrame::Array(vec![BytesFrame::SimpleString("foo".into())]).convert::<Option<String>>(),
1188      Ok(Some("foo".into()))
1189    );
1190    assert!(BytesFrame::Array(vec![
1191      BytesFrame::SimpleString("foo".into()),
1192      BytesFrame::SimpleString("bar".into())
1193    ])
1194    .convert::<Option<String>>()
1195    .is_err());
1196  }
1197
1198  #[test]
1199  fn should_convert_null_to_empty_array() {
1200    assert_eq!(Vec::<String>::new(), BytesFrame::Null.convert::<Vec<String>>().unwrap());
1201    assert_eq!(Vec::<u8>::new(), BytesFrame::Null.convert::<Vec<u8>>().unwrap());
1202  }
1203
1204  #[test]
1205  fn should_convert_to_fixed_arrays() {
1206    let foo: [i64; 2] = BytesFrame::Array(vec![BytesFrame::Integer(1), BytesFrame::Integer(2)])
1207      .convert()
1208      .unwrap();
1209    assert_eq!(foo, [1, 2]);
1210
1211    assert!(BytesFrame::Array(vec![BytesFrame::Integer(1), BytesFrame::Integer(2)])
1212      .convert::<[i64; 3]>()
1213      .is_err());
1214    assert!(BytesFrame::Array(vec![]).convert::<[i64; 3]>().is_err());
1215  }
1216}