tokio_proto/streaming/
message.rs

1use std::{cmp, fmt, ops};
2
3/// Message sent and received from a multiplexed service
4pub enum Message<T, B> {
5    /// Has no associated streaming body
6    WithoutBody(T),
7    /// Has associated streaming body
8    WithBody(T, B),
9}
10
11impl<T, B> Message<T, B> {
12    /// Returns a reference to the inner value
13    pub fn get_ref(&self) -> &T {
14        match *self {
15            Message::WithoutBody(ref v) => v,
16            Message::WithBody(ref v, _) => v,
17        }
18    }
19
20    /// Returns a mutable reference to the inner value
21    pub fn get_mut(&mut self) -> &mut T {
22        match *self {
23            Message::WithoutBody(ref mut v) => v,
24            Message::WithBody(ref mut v, _) => v,
25        }
26    }
27
28    /// Consumes the value and returns the inner value
29    pub fn into_inner(self) -> T {
30        match self {
31            Message::WithoutBody(v) => v,
32            Message::WithBody(v, _) => v,
33        }
34    }
35
36    /// If the `Message` value has an associated body stream, return it. The
37    /// original `Message` value will then become a `WithoutBody` variant.
38    pub fn take_body(&mut self) -> Option<B> {
39        use std::ptr;
40
41        // unfortunate that this is unsafe, but I think it is preferable to add
42        // a little bit of unsafe code instead of adding a useless variant to
43        // Message.
44        unsafe {
45            match ptr::read(self as *const Message<T, B>) {
46                m @ Message::WithoutBody(..) => {
47                    ptr::write(self as *mut Message<T, B>, m);
48                    None
49                }
50                Message::WithBody(m, b) => {
51                    ptr::write(self as *mut Message<T, B>, Message::WithoutBody(m));
52                    Some(b)
53                }
54            }
55        }
56    }
57}
58
59impl<T, B> cmp::PartialEq<T> for Message<T, B>
60    where T: cmp::PartialEq
61{
62    fn eq(&self, other: &T) -> bool {
63        (**self).eq(other)
64    }
65}
66
67impl<T, B> ops::Deref for Message<T, B> {
68    type Target = T;
69
70    fn deref(&self) -> &T {
71        match *self {
72            Message::WithoutBody(ref v) => v,
73            Message::WithBody(ref v, _) => v,
74        }
75    }
76}
77
78impl<T, B> ops::DerefMut for Message<T, B> {
79    fn deref_mut(&mut self) -> &mut T {
80        match *self {
81            Message::WithoutBody(ref mut v) => v,
82            Message::WithBody(ref mut v, _) => v,
83        }
84    }
85}
86
87impl<T, B> fmt::Debug for Message<T, B>
88    where T: fmt::Debug
89{
90    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
91        match *self {
92            Message::WithoutBody(ref v) => write!(fmt, "Message::WithoutBody({:?})", v),
93            Message::WithBody(ref v, _) => write!(fmt, "Message::WithBody({:?}, ...)", v),
94        }
95    }
96}