do_not_use_testing_rosidl_runtime_rs/
sequence.rs

1use std::cmp::Ordering;
2use std::fmt::{self, Debug, Display};
3use std::hash::{Hash, Hasher};
4use std::iter::{Extend, FromIterator, FusedIterator};
5use std::ops::{Deref, DerefMut};
6
7#[cfg(feature = "serde")]
8mod serde;
9
10use crate::traits::SequenceAlloc;
11
12/// An unbounded sequence.
13///
14/// The layout of a concrete `Sequence<T>` is the same as the corresponding `Sequence` struct
15/// generated by `rosidl_generator_c`. For instance,
16/// `rosidl_runtime_rs::Sequence<rosidl_runtime_rs::String>` is the same
17/// as `std_msgs__msg__String__Sequence`. See the [`Message`](crate::Message) trait for background
18/// information on this topic.
19///
20///
21/// # Example
22///
23/// ```
24/// # use rosidl_runtime_rs::{Sequence, seq};
25/// let mut list = Sequence::<i32>::new(3);
26/// // Sequences deref to slices
27/// assert_eq!(&list[..], &[0, 0, 0]);
28/// list[0] = 3;
29/// list[1] = 2;
30/// list[2] = 1;
31/// assert_eq!(&list[..], &[3, 2, 1]);
32/// // Alternatively, use the seq! macro
33/// list = seq![3, 2, 1];
34/// // The default sequence is empty
35/// assert!(Sequence::<i32>::default().is_empty());
36/// ```
37#[repr(C)]
38pub struct Sequence<T: SequenceAlloc> {
39    data: *mut T,
40    size: usize,
41    capacity: usize,
42}
43
44/// A bounded sequence.
45///
46/// The layout of a concrete `BoundedSequence<T>` is the same as the corresponding `Sequence`
47/// struct generated by `rosidl_generator_c`. For instance,
48/// `rosidl_runtime_rs::BoundedSequence<rosidl_runtime_rs::String>`
49/// is the same as `std_msgs__msg__String__Sequence`, which also represents both bounded
50/// sequences.  See the [`Message`](crate::Message) trait for background information on this
51/// topic.
52///
53/// # Example
54///
55/// ```
56/// # use rosidl_runtime_rs::{BoundedSequence, seq};
57/// let mut list = BoundedSequence::<i32, 5>::new(3);
58/// // BoundedSequences deref to slices
59/// assert_eq!(&list[..], &[0, 0, 0]);
60/// list[0] = 3;
61/// list[1] = 2;
62/// list[2] = 1;
63/// assert_eq!(&list[..], &[3, 2, 1]);
64/// // Alternatively, use the seq! macro with the length specifier
65/// list = seq![5 # 3, 2, 1];
66/// // The default bounded sequence is empty
67/// assert!(BoundedSequence::<i32, 5>::default().is_empty());
68/// ```
69#[derive(Clone)]
70#[repr(transparent)]
71pub struct BoundedSequence<T: SequenceAlloc, const N: usize> {
72    inner: Sequence<T>,
73}
74
75/// Error type for [`BoundedSequence::try_new()`].
76#[derive(Debug)]
77pub struct SequenceExceedsBoundsError {
78    /// The actual length the sequence would have after the operation.
79    pub len: usize,
80    /// The upper bound on the sequence length.
81    pub upper_bound: usize,
82}
83
84/// A by-value iterator created by [`Sequence::into_iter()`] and [`BoundedSequence::into_iter()`].
85pub struct SequenceIterator<T: SequenceAlloc> {
86    seq: Sequence<T>,
87    idx: usize,
88}
89
90// ========================= impl for Sequence =========================
91
92impl<T: SequenceAlloc> Clone for Sequence<T> {
93    fn clone(&self) -> Self {
94        let mut seq = Self::default();
95        if T::sequence_copy(self, &mut seq) {
96            seq
97        } else {
98            panic!("Cloning Sequence failed")
99        }
100    }
101}
102
103impl<T: Debug + SequenceAlloc> Debug for Sequence<T> {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
105        self.as_slice().fmt(f)
106    }
107}
108
109impl<T: SequenceAlloc> Default for Sequence<T> {
110    fn default() -> Self {
111        Self {
112            data: std::ptr::null_mut(),
113            size: 0,
114            capacity: 0,
115        }
116    }
117}
118
119impl<T: SequenceAlloc> Deref for Sequence<T> {
120    type Target = [T];
121    fn deref(&self) -> &Self::Target {
122        self.as_slice()
123    }
124}
125
126impl<T: SequenceAlloc> DerefMut for Sequence<T> {
127    fn deref_mut(&mut self) -> &mut Self::Target {
128        self.as_mut_slice()
129    }
130}
131
132impl<T: SequenceAlloc> Drop for Sequence<T> {
133    fn drop(&mut self) {
134        T::sequence_fini(self)
135    }
136}
137
138impl<T: SequenceAlloc + Eq> Eq for Sequence<T> {}
139
140impl<T: SequenceAlloc> Extend<T> for Sequence<T> {
141    fn extend<I>(&mut self, iter: I)
142    where
143        I: IntoIterator<Item = T>,
144    {
145        let it = iter.into_iter();
146        // The index in the sequence where the next element will be stored
147        let mut cur_idx = self.size;
148        // Convenience closure for resizing self
149        let resize = |seq: &mut Self, new_size: usize| {
150            let old_seq = std::mem::replace(seq, Sequence::new(new_size));
151            for (i, elem) in old_seq.into_iter().enumerate().take(new_size) {
152                seq[i] = elem;
153            }
154        };
155        // First, when there is a size hint > 0 (lower bound), make room for
156        // that many elements.
157        let num_remaining = it.size_hint().0;
158        if num_remaining > 0 {
159            let new_size = self.size.saturating_add(num_remaining);
160            resize(self, new_size);
161        }
162        for item in it {
163            // If there is no more capacity for the next element, resize to the
164            // next power of two.
165            //
166            // A pedantic implementation would check for usize overflow here, but
167            // that is hardly possible on real hardware. Also, not the entire
168            // usize address space is usable for user space programs.
169            if cur_idx == self.size {
170                let new_size = (self.size + 1).next_power_of_two();
171                resize(self, new_size);
172            }
173            self[cur_idx] = item;
174            cur_idx += 1;
175        }
176        // All items from the iterator are stored. Shrink the sequence to fit.
177        if cur_idx < self.size {
178            resize(self, cur_idx);
179        }
180    }
181}
182
183impl<T: SequenceAlloc + Clone> From<&[T]> for Sequence<T> {
184    fn from(slice: &[T]) -> Self {
185        let mut seq = Sequence::new(slice.len());
186        seq.clone_from_slice(slice);
187        seq
188    }
189}
190
191impl<T: SequenceAlloc> From<Vec<T>> for Sequence<T> {
192    fn from(v: Vec<T>) -> Self {
193        Sequence::from_iter(v)
194    }
195}
196
197impl<T: SequenceAlloc> FromIterator<T> for Sequence<T> {
198    fn from_iter<I>(iter: I) -> Self
199    where
200        I: IntoIterator<Item = T>,
201    {
202        let mut seq = Sequence::new(0);
203        seq.extend(iter);
204        seq
205    }
206}
207
208impl<T: SequenceAlloc + Hash> Hash for Sequence<T> {
209    fn hash<H: Hasher>(&self, state: &mut H) {
210        self.as_slice().hash(state)
211    }
212}
213
214impl<T: SequenceAlloc> IntoIterator for Sequence<T> {
215    type Item = T;
216    type IntoIter = SequenceIterator<T>;
217    fn into_iter(self) -> Self::IntoIter {
218        SequenceIterator { seq: self, idx: 0 }
219    }
220}
221
222impl<T: SequenceAlloc + Ord> Ord for Sequence<T> {
223    fn cmp(&self, other: &Self) -> Ordering {
224        self.as_slice().cmp(other.as_slice())
225    }
226}
227
228impl<T: SequenceAlloc + PartialEq> PartialEq for Sequence<T> {
229    fn eq(&self, other: &Self) -> bool {
230        self.as_slice().eq(other.as_slice())
231    }
232}
233
234impl<T: SequenceAlloc + PartialOrd> PartialOrd for Sequence<T> {
235    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
236        self.as_slice().partial_cmp(other.as_slice())
237    }
238}
239
240// SAFETY: A sequence is a simple data structure, and therefore not thread-specific.
241unsafe impl<T: Send + SequenceAlloc> Send for Sequence<T> {}
242// SAFETY: A sequence does not have interior mutability, so it can be shared.
243unsafe impl<T: Sync + SequenceAlloc> Sync for Sequence<T> {}
244
245impl<T> Sequence<T>
246where
247    T: SequenceAlloc,
248{
249    /// Creates a sequence of `len` elements with default values.
250    pub fn new(len: usize) -> Self {
251        let mut seq = Self::default();
252        if !T::sequence_init(&mut seq, len) {
253            panic!("Sequence initialization failed");
254        }
255        seq
256    }
257
258    /// Extracts a slice containing the entire sequence.
259    ///
260    /// Equivalent to `&seq[..]`.
261    pub fn as_slice(&self) -> &[T] {
262        // SAFETY: self.data points to self.size consecutive, initialized elements and
263        // isn't modified externally.
264        unsafe { std::slice::from_raw_parts(self.data, self.size) }
265    }
266
267    /// Extracts a mutable slice containing the entire sequence.
268    ///
269    /// Equivalent to `&mut seq[..]`.
270    pub fn as_mut_slice(&mut self) -> &mut [T] {
271        // SAFETY: self.data points to self.size consecutive, initialized elements and
272        // isn't modified externally.
273        unsafe { std::slice::from_raw_parts_mut(self.data, self.size) }
274    }
275}
276
277// ========================= impl for BoundedSequence =========================
278
279impl<T: Debug + SequenceAlloc, const N: usize> Debug for BoundedSequence<T, N> {
280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
281        self.as_slice().fmt(f)
282    }
283}
284
285impl<T: SequenceAlloc, const N: usize> Default for BoundedSequence<T, N> {
286    fn default() -> Self {
287        Self {
288            inner: Sequence {
289                data: std::ptr::null_mut(),
290                size: 0,
291                capacity: 0,
292            },
293        }
294    }
295}
296
297impl<T: SequenceAlloc, const N: usize> Deref for BoundedSequence<T, N> {
298    type Target = [T];
299    fn deref(&self) -> &Self::Target {
300        self.inner.deref()
301    }
302}
303
304impl<T: SequenceAlloc, const N: usize> DerefMut for BoundedSequence<T, N> {
305    fn deref_mut(&mut self) -> &mut Self::Target {
306        self.inner.deref_mut()
307    }
308}
309
310impl<T: SequenceAlloc, const N: usize> Drop for BoundedSequence<T, N> {
311    fn drop(&mut self) {
312        T::sequence_fini(&mut self.inner)
313    }
314}
315
316impl<T: SequenceAlloc + Eq, const N: usize> Eq for BoundedSequence<T, N> {}
317
318impl<T: SequenceAlloc, const N: usize> Extend<T> for BoundedSequence<T, N> {
319    fn extend<I>(&mut self, iter: I)
320    where
321        I: IntoIterator<Item = T>,
322    {
323        self.inner
324            .extend(iter.into_iter().take(N - self.inner.size));
325    }
326}
327
328impl<T: SequenceAlloc + Clone, const N: usize> TryFrom<&[T]> for BoundedSequence<T, N> {
329    type Error = SequenceExceedsBoundsError;
330    fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
331        let mut seq = BoundedSequence::try_new(slice.len())?;
332        seq.clone_from_slice(slice);
333        Ok(seq)
334    }
335}
336
337impl<T: SequenceAlloc, const N: usize> TryFrom<Vec<T>> for BoundedSequence<T, N> {
338    type Error = SequenceExceedsBoundsError;
339    fn try_from(v: Vec<T>) -> Result<Self, Self::Error> {
340        if v.len() > N {
341            Err(SequenceExceedsBoundsError {
342                len: v.len(),
343                upper_bound: N,
344            })
345        } else {
346            Ok(BoundedSequence::from_iter(v))
347        }
348    }
349}
350
351impl<T: SequenceAlloc, const N: usize> FromIterator<T> for BoundedSequence<T, N> {
352    fn from_iter<I>(iter: I) -> Self
353    where
354        I: IntoIterator<Item = T>,
355    {
356        let mut seq = BoundedSequence::new(0);
357        seq.extend(iter);
358        seq
359    }
360}
361
362impl<T: SequenceAlloc + Hash, const N: usize> Hash for BoundedSequence<T, N> {
363    fn hash<H: Hasher>(&self, state: &mut H) {
364        self.as_slice().hash(state)
365    }
366}
367
368impl<T: SequenceAlloc, const N: usize> IntoIterator for BoundedSequence<T, N> {
369    type Item = T;
370    type IntoIter = SequenceIterator<T>;
371    fn into_iter(mut self) -> Self::IntoIter {
372        let seq = std::mem::replace(
373            &mut self.inner,
374            Sequence {
375                data: std::ptr::null_mut(),
376                size: 0,
377                capacity: 0,
378            },
379        );
380        SequenceIterator { seq, idx: 0 }
381    }
382}
383
384impl<T: SequenceAlloc + Ord, const N: usize> Ord for BoundedSequence<T, N> {
385    fn cmp(&self, other: &Self) -> Ordering {
386        self.as_slice().cmp(other.as_slice())
387    }
388}
389
390impl<T: SequenceAlloc + PartialEq, const N: usize> PartialEq for BoundedSequence<T, N> {
391    fn eq(&self, other: &Self) -> bool {
392        self.as_slice().eq(other.as_slice())
393    }
394}
395
396impl<T: SequenceAlloc + PartialOrd, const N: usize> PartialOrd for BoundedSequence<T, N> {
397    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
398        self.as_slice().partial_cmp(other.as_slice())
399    }
400}
401
402impl<T, const N: usize> BoundedSequence<T, N>
403where
404    T: SequenceAlloc,
405{
406    /// Creates a sequence of `len` elements with default values.
407    ///
408    /// If `len` is greater than `N`, this function panics.
409    pub fn new(len: usize) -> Self {
410        Self::try_new(len).unwrap()
411    }
412
413    /// Attempts to create a sequence of `len` elements with default values.
414    ///
415    /// If `len` is greater than `N`, this function returns an error.
416    pub fn try_new(len: usize) -> Result<Self, SequenceExceedsBoundsError> {
417        if len > N {
418            return Err(SequenceExceedsBoundsError {
419                len,
420                upper_bound: N,
421            });
422        }
423        let mut seq = Self::default();
424        if !T::sequence_init(&mut seq.inner, len) {
425            panic!("BoundedSequence initialization failed");
426        }
427        Ok(seq)
428    }
429
430    /// Extracts a slice containing the entire sequence.
431    ///
432    /// Equivalent to `&seq[..]`.
433    pub fn as_slice(&self) -> &[T] {
434        self.inner.as_slice()
435    }
436
437    /// Extracts a mutable slice containing the entire sequence.
438    ///
439    /// Equivalent to `&mut seq[..]`.
440    pub fn as_mut_slice(&mut self) -> &mut [T] {
441        self.inner.as_mut_slice()
442    }
443}
444
445// ========================= impl for SequenceIterator =========================
446
447impl<T: SequenceAlloc> Iterator for SequenceIterator<T> {
448    type Item = T;
449    fn next(&mut self) -> Option<Self::Item> {
450        if self.idx >= self.seq.size {
451            return None;
452        }
453        // SAFETY: data + idx is in bounds and points to a valid value
454        let elem = unsafe {
455            let ptr = self.seq.data.add(self.idx);
456            let elem = ptr.read();
457            // Need to make sure that dropping the sequence later will not fini() the elements
458            ptr.write(std::mem::zeroed::<T>());
459            elem
460        };
461        self.idx += 1;
462        Some(elem)
463    }
464
465    fn size_hint(&self) -> (usize, Option<usize>) {
466        let len = (self.seq.size + 1) - self.idx;
467        (len, Some(len))
468    }
469}
470
471impl<T: SequenceAlloc> ExactSizeIterator for SequenceIterator<T> {
472    fn len(&self) -> usize {
473        (self.seq.size + 1) - self.idx
474    }
475}
476
477impl<T: SequenceAlloc> FusedIterator for SequenceIterator<T> {}
478
479// ========================= impl for StringExceedsBoundsError =========================
480
481impl Display for SequenceExceedsBoundsError {
482    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
483        write!(
484            f,
485            "BoundedSequence with upper bound {} initialized with len {}",
486            self.upper_bound, self.len
487        )
488    }
489}
490
491impl std::error::Error for SequenceExceedsBoundsError {}
492
493macro_rules! impl_sequence_alloc_for_primitive_type {
494    ($rust_type:ty, $init_func:ident, $fini_func:ident, $copy_func:ident) => {
495        #[link(name = "rosidl_runtime_c")]
496        extern "C" {
497            fn $init_func(seq: *mut Sequence<$rust_type>, size: usize) -> bool;
498            fn $fini_func(seq: *mut Sequence<$rust_type>);
499            fn $copy_func(
500                in_seq: *const Sequence<$rust_type>,
501                out_seq: *mut Sequence<$rust_type>,
502            ) -> bool;
503        }
504
505        impl SequenceAlloc for $rust_type {
506            fn sequence_init(seq: &mut Sequence<Self>, size: usize) -> bool {
507                // SAFETY: There are no special preconditions to the sequence_init function.
508                unsafe {
509                    // This allocates space and sets seq.size and seq.capacity to size
510                    let ret = $init_func(seq as *mut _, size);
511                    // Zero memory, since it will be uninitialized if there is no default value
512                    std::ptr::write_bytes(seq.data, 0u8, size);
513                    ret
514                }
515            }
516            fn sequence_fini(seq: &mut Sequence<Self>) {
517                // SAFETY: There are no special preconditions to the sequence_fini function.
518                unsafe { $fini_func(seq as *mut _) }
519            }
520            fn sequence_copy(in_seq: &Sequence<Self>, out_seq: &mut Sequence<Self>) -> bool {
521                // SAFETY: There are no special preconditions to the sequence_copy function.
522                unsafe { $copy_func(in_seq as *const _, out_seq as *mut _) }
523            }
524        }
525    };
526}
527
528// Primitives are not messages themselves, but there can be sequences of them.
529//
530// See https://github.com/ros2/rosidl/blob/master/rosidl_runtime_c/include/rosidl_runtime_c/primitives_sequence.h
531// Long double isn't available in Rust, so it is skipped.
532impl_sequence_alloc_for_primitive_type!(
533    f32,
534    rosidl_runtime_c__float__Sequence__init,
535    rosidl_runtime_c__float__Sequence__fini,
536    rosidl_runtime_c__float__Sequence__copy
537);
538impl_sequence_alloc_for_primitive_type!(
539    f64,
540    rosidl_runtime_c__double__Sequence__init,
541    rosidl_runtime_c__double__Sequence__fini,
542    rosidl_runtime_c__double__Sequence__copy
543);
544impl_sequence_alloc_for_primitive_type!(
545    bool,
546    rosidl_runtime_c__boolean__Sequence__init,
547    rosidl_runtime_c__boolean__Sequence__fini,
548    rosidl_runtime_c__boolean__Sequence__copy
549);
550impl_sequence_alloc_for_primitive_type!(
551    u8,
552    rosidl_runtime_c__uint8__Sequence__init,
553    rosidl_runtime_c__uint8__Sequence__fini,
554    rosidl_runtime_c__uint8__Sequence__copy
555);
556impl_sequence_alloc_for_primitive_type!(
557    i8,
558    rosidl_runtime_c__int8__Sequence__init,
559    rosidl_runtime_c__int8__Sequence__fini,
560    rosidl_runtime_c__int8__Sequence__copy
561);
562impl_sequence_alloc_for_primitive_type!(
563    u16,
564    rosidl_runtime_c__uint16__Sequence__init,
565    rosidl_runtime_c__uint16__Sequence__fini,
566    rosidl_runtime_c__uint16__Sequence__copy
567);
568impl_sequence_alloc_for_primitive_type!(
569    i16,
570    rosidl_runtime_c__int16__Sequence__init,
571    rosidl_runtime_c__int16__Sequence__fini,
572    rosidl_runtime_c__int16__Sequence__copy
573);
574impl_sequence_alloc_for_primitive_type!(
575    u32,
576    rosidl_runtime_c__uint32__Sequence__init,
577    rosidl_runtime_c__uint32__Sequence__fini,
578    rosidl_runtime_c__uint32__Sequence__copy
579);
580impl_sequence_alloc_for_primitive_type!(
581    i32,
582    rosidl_runtime_c__int32__Sequence__init,
583    rosidl_runtime_c__int32__Sequence__fini,
584    rosidl_runtime_c__int32__Sequence__copy
585);
586impl_sequence_alloc_for_primitive_type!(
587    u64,
588    rosidl_runtime_c__uint64__Sequence__init,
589    rosidl_runtime_c__uint64__Sequence__fini,
590    rosidl_runtime_c__uint64__Sequence__copy
591);
592impl_sequence_alloc_for_primitive_type!(
593    i64,
594    rosidl_runtime_c__int64__Sequence__init,
595    rosidl_runtime_c__int64__Sequence__fini,
596    rosidl_runtime_c__int64__Sequence__copy
597);
598
599/// Creates a sequence, similar to the `vec!` macro.
600///
601/// It's possible to create both [`Sequence`]s and [`BoundedSequence`]s.
602/// Unbounded sequences are created by a comma-separated list of values.
603/// Bounded sequences are created by additionally specifying the maximum capacity (the `N` type
604/// parameter) in the beginning, followed by a `#`.
605///
606/// # Example
607/// ```
608/// # use rosidl_runtime_rs::{BoundedSequence, Sequence, seq};
609/// let unbounded: Sequence<i32> = seq![1, 2, 3];
610/// let bounded: BoundedSequence<i32, 5> = seq![5 # 1, 2, 3];
611/// assert_eq!(&unbounded[..], &bounded[..])
612/// ```
613#[macro_export]
614macro_rules! seq {
615    [$( $elem:expr ),*] => {
616        {
617            let len = seq!(@count_tts $($elem),*);
618            let mut seq = Sequence::new(len);
619            let mut i = 0;
620            $(
621                seq[i] = $elem;
622                #[allow(unused_assignments)]
623                { i += 1; }
624            )*
625            seq
626        }
627    };
628    [$len:literal # $( $elem:expr ),*] => {
629        {
630            let len = seq!(@count_tts $($elem),*);
631            let mut seq = BoundedSequence::<_, $len>::new(len);
632            let mut i = 0;
633            $(
634                seq[i] = $elem;
635                #[allow(unused_assignments)]
636                { i += 1; }
637            )*
638            seq
639        }
640    };
641    // https://danielkeep.github.io/tlborm/book/blk-counting.html
642    (@replace_expr ($_t:expr, $sub:expr)) => {$sub};
643    (@count_tts $($e:expr),*) => {<[()]>::len(&[$(seq!(@replace_expr ($e, ()))),*])};
644}
645
646#[cfg(test)]
647mod tests {
648    use quickcheck::{quickcheck, Arbitrary, Gen};
649
650    use super::*;
651
652    impl<T: Arbitrary + SequenceAlloc> Arbitrary for Sequence<T> {
653        fn arbitrary(g: &mut Gen) -> Self {
654            Vec::arbitrary(g).into()
655        }
656    }
657
658    impl<T: Arbitrary + SequenceAlloc> Arbitrary for BoundedSequence<T, 256> {
659        fn arbitrary(g: &mut Gen) -> Self {
660            let len = u8::arbitrary(g);
661            (0..len).map(|_| T::arbitrary(g)).collect()
662        }
663    }
664
665    quickcheck! {
666        fn test_extend(xs: Vec<i32>, ys: Vec<i32>) -> bool {
667            let mut xs_seq = Sequence::new(xs.len());
668            xs_seq.copy_from_slice(&xs);
669            xs_seq.extend(ys.clone());
670            if xs_seq.len() != xs.len() + ys.len() {
671                return false;
672            }
673            if xs_seq[..xs.len()] != xs[..] {
674                return false;
675            }
676            if xs_seq[xs.len()..] != ys[..] {
677                return false;
678            }
679            true
680        }
681    }
682
683    quickcheck! {
684        fn test_iteration(xs: Vec<i32>) -> bool {
685            let mut seq_1 = Sequence::new(xs.len());
686            seq_1.copy_from_slice(&xs);
687            let seq_2 = seq_1.clone().into_iter().collect();
688            seq_1 == seq_2
689        }
690    }
691}