11//! Types wrapping typed data.
22
3- use std:: sync:: Arc ;
43use bytes:: arc:: Bytes ;
54use crate :: Data ;
65
7- /// Either an immutable or mutable reference.
8- pub enum RefOrMut < ' a , T > where T : ' a {
9- /// An immutable reference.
10- Ref ( & ' a T ) ,
11- /// A mutable reference.
12- Mut ( & ' a mut T ) ,
13- }
14-
15- impl < ' a , T : ' a > :: std:: ops:: Deref for RefOrMut < ' a , T > {
16- type Target = T ;
17- fn deref ( & self ) -> & Self :: Target {
18- match self {
19- RefOrMut :: Ref ( reference) => reference,
20- RefOrMut :: Mut ( reference) => reference,
21- }
22- }
23- }
24-
25- impl < ' a , T : ' a > :: std:: borrow:: Borrow < T > for RefOrMut < ' a , T > {
26- fn borrow ( & self ) -> & T {
27- match self {
28- RefOrMut :: Ref ( reference) => reference,
29- RefOrMut :: Mut ( reference) => reference,
30- }
31- }
32- }
33-
34- impl < ' a , T : Clone +' a > RefOrMut < ' a , T > {
35- /// Extracts the contents of `self`, either by cloning or swapping.
36- ///
37- /// This consumes `self` because its contents are now in an unknown state.
38- pub fn swap < ' b > ( self , element : & ' b mut T ) {
39- match self {
40- RefOrMut :: Ref ( reference) => element. clone_from ( reference) ,
41- RefOrMut :: Mut ( reference) => :: std:: mem:: swap ( reference, element) ,
42- } ;
43- }
44- /// Extracts the contents of `self`, either by cloning or swapping.
45- ///
46- /// This consumes `self` because its contents are now in an unknown state.
47- pub fn replace ( self , mut element : T ) -> T {
48- self . swap ( & mut element) ;
49- element
50- }
51-
52- /// Extracts the contents of `self`, either by cloning, or swapping and leaving a default
53- /// element in place.
54- ///
55- /// This consumes `self` because its contents are now in an unknown state.
56- pub fn take ( self ) -> T where T : Default {
57- let mut element = Default :: default ( ) ;
58- self . swap ( & mut element) ;
59- element
60- }
61- }
62-
63- /// A wrapped message which may be either typed or binary data.
6+ /// A wrapped message which supports serialization and deserialization.
647pub struct Message < T > {
65- payload : MessageContents < T > ,
66- }
67-
68- /// Possible returned representations from a channel.
69- enum MessageContents < T > {
70- /// Rust typed instance. Available for ownership.
71- Owned ( T ) ,
72- /// Atomic reference counted. Only available as a reference.
73- Arc ( Arc < T > ) ,
8+ /// Message contents.
9+ pub payload : T ,
7410}
7511
7612impl < T > Message < T > {
7713 /// Wrap a typed item as a message.
7814 pub fn from_typed ( typed : T ) -> Self {
79- Message { payload : MessageContents :: Owned ( typed) }
80- }
81- /// Wrap a shared typed item as a message.
82- pub fn from_arc ( typed : Arc < T > ) -> Self {
83- Message { payload : MessageContents :: Arc ( typed) }
84- }
85- /// Destructures and returns any typed data.
86- pub fn if_typed ( self ) -> Option < T > {
87- match self . payload {
88- MessageContents :: Owned ( typed) => Some ( typed) ,
89- MessageContents :: Arc ( _) => None ,
90- }
91- }
92- /// Returns a mutable reference, if typed.
93- pub fn if_mut ( & mut self ) -> Option < & mut T > {
94- match & mut self . payload {
95- MessageContents :: Owned ( typed) => Some ( typed) ,
96- MessageContents :: Arc ( _) => None ,
97- }
98- }
99- /// Returns an immutable or mutable typed reference.
100- ///
101- /// This method returns a mutable reference if the underlying data are typed Rust
102- /// instances, which admit mutation, and it returns an immutable reference if the
103- /// data are serialized binary data.
104- pub fn as_ref_or_mut ( & mut self ) -> RefOrMut < T > {
105- match & mut self . payload {
106- MessageContents :: Owned ( typed) => { RefOrMut :: Mut ( typed) } ,
107- MessageContents :: Arc ( typed) => { RefOrMut :: Ref ( typed) } ,
108- }
15+ Message { payload : typed }
10916 }
11017}
11118
11219impl < T : Data > Message < T > {
11320 /// Wrap bytes as a message.
11421 pub fn from_bytes ( bytes : Bytes ) -> Self {
11522 let typed = :: bincode:: deserialize ( & bytes[ ..] ) . expect ( "bincode::deserialize() failed" ) ;
116- Message { payload : MessageContents :: Owned ( typed) }
23+ Message { payload : typed }
11724 }
11825
11926 /// The number of bytes required to serialize the data.
12027 pub fn length_in_bytes ( & self ) -> usize {
121- match & self . payload {
122- MessageContents :: Owned ( typed) => {
123- :: bincode:: serialized_size ( & typed) . expect ( "bincode::serialized_size() failed" ) as usize
124- } ,
125- MessageContents :: Arc ( typed) => {
126- :: bincode:: serialized_size ( & * * typed) . expect ( "bincode::serialized_size() failed" ) as usize
127- } ,
128- }
28+ :: bincode:: serialized_size ( & self . payload ) . expect ( "bincode::serialized_size() failed" ) as usize
12929 }
13030
13131 /// Writes the binary representation into `writer`.
13232 pub fn into_bytes < W : :: std:: io:: Write > ( & self , writer : & mut W ) {
133- match & self . payload {
134- MessageContents :: Owned ( typed) => {
135- :: bincode:: serialize_into ( writer, & typed) . expect ( "bincode::serialize_into() failed" ) ;
136- } ,
137- MessageContents :: Arc ( typed) => {
138- :: bincode:: serialize_into ( writer, & * * typed) . expect ( "bincode::serialize_into() failed" ) ;
139- } ,
140- }
33+ :: bincode:: serialize_into ( writer, & self . payload ) . expect ( "bincode::serialize_into() failed" ) ;
14134 }
14235}
14336
14437impl < T > :: std:: ops:: Deref for Message < T > {
14538 type Target = T ;
14639 fn deref ( & self ) -> & Self :: Target {
147- // TODO: In principle we have already decoded, but let's go again
148- match & self . payload {
149- MessageContents :: Owned ( typed) => { typed } ,
150- MessageContents :: Arc ( typed) => { typed } ,
151- }
40+ & self . payload
15241 }
15342}
154-
155- impl < T : Clone > Message < T > {
156- /// Produces a typed instance of the wrapped element.
157- pub fn into_typed ( self ) -> T {
158- match self . payload {
159- MessageContents :: Owned ( instance) => instance,
160- // TODO: Could attempt `Arc::try_unwrap()` here.
161- MessageContents :: Arc ( instance) => ( * instance) . clone ( ) ,
162- }
163- }
164- /// Ensures the message is typed data and returns a mutable reference to it.
165- pub fn as_mut ( & mut self ) -> & mut T {
166-
167- let cloned: Option < T > = match & self . payload {
168- MessageContents :: Owned ( _) => None ,
169- // TODO: Could attempt `Arc::try_unwrap()` here.
170- MessageContents :: Arc ( typed) => Some ( ( * * typed) . clone ( ) ) ,
171- } ;
172-
173- if let Some ( cloned) = cloned {
174- self . payload = MessageContents :: Owned ( cloned) ;
175- }
176-
177- if let MessageContents :: Owned ( typed) = & mut self . payload {
178- typed
179- }
180- else {
181- unreachable ! ( )
182- }
183- }
184- }
0 commit comments