mail_internals/encoder/
encodable.rs1use std::any::{Any, TypeId};
2use std::fmt::{self, Debug};
3use std::result::{ Result as StdResult };
4use std::sync::Arc;
5
6use ::error::EncodingError;
7use super::{EncodingWriter};
8
9pub trait EncodableInHeader: Send + Sync + Any + Debug {
16 fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError>;
17
18 fn boxed_clone(&self) -> Box<EncodableInHeader>;
19
20 #[doc(hidden)]
21 fn type_id(&self) -> TypeId {
22 TypeId::of::<Self>()
23 }
24}
25
26impl EncodableInHeader {
28
29 #[inline(always)]
30 pub fn is<T: EncodableInHeader>(&self) -> bool {
31 EncodableInHeader::type_id(self) == TypeId::of::<T>()
32 }
33
34
35 #[inline]
36 pub fn downcast_ref<T: EncodableInHeader>(&self) -> Option<&T> {
37 if self.is::<T>() {
38 Some( unsafe { &*( self as *const EncodableInHeader as *const T) } )
39 } else {
40 None
41 }
42 }
43
44 #[inline]
45 pub fn downcast_mut<T: EncodableInHeader>(&mut self) -> Option<&mut T> {
46 if self.is::<T>() {
47 Some( unsafe { &mut *( self as *mut EncodableInHeader as *mut T) } )
48 } else {
49 None
50 }
51 }
52}
53
54impl Clone for Box<EncodableInHeader> {
55
56 fn clone(&self) -> Self {
57 self.boxed_clone()
58 }
59}
60
61
62pub trait EncodableInHeaderBoxExt: Sized {
63 fn downcast<T: EncodableInHeader>(self) -> StdResult<Box<T>, Self>;
64}
65
66impl EncodableInHeaderBoxExt for Box<EncodableInHeader> {
67
68 fn downcast<T: EncodableInHeader>(self) -> StdResult<Box<T>, Self> {
69 if EncodableInHeader::is::<T>(&*self) {
70 let ptr: *mut EncodableInHeader = Box::into_raw(self);
71 Ok( unsafe { Box::from_raw(ptr as *mut T) } )
72 } else {
73 Err( self )
74 }
75 }
76}
77
78impl EncodableInHeaderBoxExt for Box<EncodableInHeader+Send> {
79
80 fn downcast<T: EncodableInHeader>(self) -> StdResult<Box<T>, Self> {
81 if EncodableInHeader::is::<T>(&*self) {
82 let ptr: *mut EncodableInHeader = Box::into_raw(self);
83 Ok( unsafe { Box::from_raw(ptr as *mut T) } )
84 } else {
85 Err( self )
86 }
87 }
88}
89
90#[macro_export]
94macro_rules! enc_func {
95 (|$enc:ident : &mut EncodingWriter| $block:block) => ({
96 use $crate::error::EncodingError;
97 fn _anonym($enc: &mut EncodingWriter) -> Result<(), EncodingError> {
98 $block
99 }
100 let fn_pointer = _anonym as fn(&mut EncodingWriter) -> Result<(), EncodingError>;
101 $crate::encoder::EncodeFn::new(fn_pointer)
102 });
103}
104
105type _EncodeFn = for<'a, 'b> fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>;
106
107#[derive(Clone, Copy)]
109pub struct EncodeFn(_EncodeFn);
110
111impl EncodeFn {
112 pub fn new(func: _EncodeFn) -> Self {
113 EncodeFn(func)
114 }
115}
116
117impl EncodableInHeader for EncodeFn {
118 fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
119 (self.0)(encoder)
120 }
121
122 fn boxed_clone(&self) -> Box<EncodableInHeader> {
123 Box::new(*self)
124 }
125}
126
127impl Debug for EncodeFn {
128 fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
129 write!(fter, "EncodeFn(..)")
130 }
131}
132
133#[macro_export]
137macro_rules! enc_closure {
138 ($($t:tt)*) => ({
139 $crate::encoder::EncodeClosure::new($($t)*)
140 });
141}
142
143pub struct EncodeClosure<FN: 'static>(Arc<FN>)
145 where FN: Send + Sync +
146 for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>;
147
148impl<FN: 'static> EncodeClosure<FN>
149 where FN: Send + Sync +
150 for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
151{
152 pub fn new(closure: FN) -> Self {
153 EncodeClosure(Arc::new(closure))
154 }
155}
156
157impl<FN: 'static> EncodableInHeader for EncodeClosure<FN>
158 where FN: Send + Sync +
159 for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
160{
161 fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
162 (self.0)(encoder)
163 }
164
165 fn boxed_clone(&self) -> Box<EncodableInHeader> {
166 Box::new(self.clone())
167 }
168}
169
170impl<FN: 'static> Clone for EncodeClosure<FN>
171 where FN: Send + Sync +
172 for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
173{
174 fn clone(&self) -> Self {
175 EncodeClosure(self.0.clone())
176 }
177}
178
179
180impl<FN: 'static> Debug for EncodeClosure<FN>
181 where FN: Send + Sync +
182 for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
183{
184 fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
185 write!(fter, "EncodeClosure(..)")
186 }
187}