1use std::{cell::RefCell, ops, rc::Rc};
2
3use bitflags::bitflags;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ConnectionType {
8 Close,
10
11 KeepAlive,
13
14 Upgrade,
16}
17
18bitflags! {
19 #[derive(Debug, Clone, Copy)]
20 pub(crate) struct Flags: u8 {
21 const CLOSE = 0b0000_0001;
22 const KEEP_ALIVE = 0b0000_0010;
23 const UPGRADE = 0b0000_0100;
24 const EXPECT = 0b0000_1000;
25 const NO_CHUNKING = 0b0001_0000;
26 const CAMEL_CASE = 0b0010_0000;
27 }
28}
29
30#[doc(hidden)]
31pub trait Head: Default + 'static {
32 fn clear(&mut self);
33
34 fn with_pool<F, R>(f: F) -> R
35 where
36 F: FnOnce(&MessagePool<Self>) -> R;
37}
38
39pub struct Message<T: Head> {
40 head: Rc<T>,
43}
44
45impl<T: Head> Message<T> {
46 #[allow(clippy::new_without_default)]
48 pub fn new() -> Self {
49 T::with_pool(MessagePool::get_message)
50 }
51}
52
53impl<T: Head> ops::Deref for Message<T> {
54 type Target = T;
55
56 fn deref(&self) -> &Self::Target {
57 self.head.as_ref()
58 }
59}
60
61impl<T: Head> ops::DerefMut for Message<T> {
62 fn deref_mut(&mut self) -> &mut Self::Target {
63 Rc::get_mut(&mut self.head).expect("Multiple copies exist")
64 }
65}
66
67impl<T: Head> Drop for Message<T> {
68 fn drop(&mut self) {
69 T::with_pool(|p| p.release(Rc::clone(&self.head)))
70 }
71}
72
73#[doc(hidden)]
75pub struct MessagePool<T: Head>(RefCell<Vec<Rc<T>>>);
76
77impl<T: Head> MessagePool<T> {
78 pub(crate) fn create() -> MessagePool<T> {
79 MessagePool(RefCell::new(Vec::with_capacity(128)))
80 }
81
82 #[inline]
84 fn get_message(&self) -> Message<T> {
85 if let Some(mut msg) = self.0.borrow_mut().pop() {
86 Rc::get_mut(&mut msg)
89 .expect("Multiple copies exist")
90 .clear();
91 Message { head: msg }
92 } else {
93 Message {
94 head: Rc::new(T::default()),
95 }
96 }
97 }
98
99 #[inline]
100 fn release(&self, msg: Rc<T>) {
102 let pool = &mut self.0.borrow_mut();
103 if pool.len() < 128 {
104 pool.push(msg);
105 }
106 }
107}