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
128pub trait FromResp2<F: Resp2Frame>: Sized {
130 fn from_frame(frame: F) -> Result<Self, RedisProtocolError>;
132
133 fn from_frames(frames: Vec<F>) -> Result<Vec<Self>, RedisProtocolError> {
135 frames.into_iter().map(Self::from_frame).collect()
136 }
137
138 #[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 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 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 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 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 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#[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}