push_trait/
append.rs

1//! Traits for moving data between collectinos without freeing resources.
2
3cfg_if! {
4    if #[cfg(feature = "std")] {
5        use std::mem::swap;
6    } else {
7        use core::mem::swap;
8    }
9}
10
11use len_trait::Clear;
12
13use base::{CanPush, Push};
14use ordered::{PushBack, PushFront};
15
16/// A trait for moving data from one collection into another without freeing resources.
17///
18/// Conceptually, an `append` is equivalent to a [`push`], with the caveat that the data is "moved
19/// out" of the pushed collection instead of being consumed. This allows reuse of the pushed
20/// collection's resources.
21///
22/// [`push`]: ../base/trait.Push.html#tymethod.push
23pub trait Append: Sized + Clear {
24    /// Moves data out of `val` and into this collection.
25    ///
26    /// Invoking this method should make `val` empty without freeing any resources. Any data that
27    /// would be pushed out of `self` should be retained in `val`.
28    fn append(&mut self, val: &mut Self);
29}
30impl<T: Append> CanPush<T> for T {
31    type PushedOut = T;
32}
33impl<T: Append> Push<T> for T {
34    fn push(&mut self, mut val: T) -> Option<T> {
35        self.append(&mut val);
36        if val.is_empty() { None } else { Some(val) }
37    }
38}
39
40/// A trait for moving data from one collection onto the back of another without freeing resources.
41///
42/// This trait is the [`PushBack`] analogue of [`Append`].
43///
44/// [`PushBack`]: ../ordered/trait.PushBack.html
45/// [`Append`]: trait.Append.html
46pub trait AppendBack: Append {
47    /// Moves data out of `val` and onto the back of this collection.
48    ///
49    /// Invoking this method should make `val` empty without freeing any resources.
50    fn append_back(&mut self, val: &mut Self) {
51        self.append(val)
52    }
53}
54impl<T: AppendBack> PushBack<T> for T {}
55
56/// A trait for moving data from one collection onto the front of another without freeing resources.
57///
58/// This trait is the [`PushFront`] analogue of [`Append`].
59///
60/// [`PushFront`]: ../ordered/trait.PushBack.html
61/// [`Append`]: trait.Append.html
62pub trait AppendFront: AppendBack {
63    /// Moves data out of `val` and onto the front of this collection.
64    ///
65    /// Invoking this method should make `val` empty without freeing any resources.
66    fn append_front(&mut self, val: &mut Self) {
67        swap(val, self);
68        val.append_back(self)
69    }
70}
71impl<T: AppendFront> PushFront<T> for T {
72    fn push_front(&mut self, mut val: T) -> Option<T> {
73        self.append_front(&mut val);
74        if val.is_empty() { None } else { Some(val) }
75    }
76}