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}