1use std::any::Any;
2use std::collections::HashMap;
3
4pub trait Packet {
6
7 fn as_any(&self) -> &dyn Any;
9
10 fn get_name(&self) -> &'static str;
12
13 fn object_field_names(&self) -> Vec<&'static str>;
15
16 fn object_type_names(&self) -> Vec<&'static str>;
18
19 fn get_values(&self) -> Vec<Box<dyn std::any::Any>>;
21}
22
23pub struct PacketWrapper {
25
26 fields_accessor: Option<Box<dyn Fn() -> Vec<&'static str> + Send + Sync>>,
28
29 instance_accessor: Option<Box<dyn Fn(Vec<Box<dyn Any>>) -> Box<dyn Packet + Send + Sync> + Send + Sync>>,
31
32 types_accessor: Option<Box<dyn Fn() -> Vec<&'static str> + Send + Sync>>
34}
35
36impl PacketWrapper {
38
39 pub fn new(
41 fields_accessor: Option<Box<dyn Fn() -> Vec<&'static str> + Send + Sync>>,
42 instance_accessor: Option<Box<dyn Fn(Vec<Box<dyn Any>>) -> Box<dyn Packet + Send + Sync> + Send + Sync>>,
43 types_accessor: Option<Box<dyn Fn() -> Vec<&'static str> + Send + Sync>>) -> Self {
44 Self {
45 fields_accessor,
46 instance_accessor,
47 types_accessor
48 }
49 }
50
51 pub fn create_instance<T: Packet + Clone + Send + Sync + 'static>(&self, data: Vec<Box<dyn Any>>) -> T {
53 let boxed_packet: &Box<dyn Packet + Send + Sync> = &self.instance_accessor.as_ref().unwrap().as_ref()(data);
54 crate::cast_packet!(boxed_packet as T)
55 }
56
57 pub fn create_instance_box(&self, data: Vec<Box<dyn Any>>) -> Box<dyn Packet + Send + Sync> {
58 let boxed_packet: Box<dyn Packet + Send + Sync> = self.instance_accessor.as_ref().unwrap().as_ref()(data);
59 boxed_packet
60 }
61
62 pub fn get_fields(&self) -> Vec<&'static str> {
64 let fields: Vec<&'static str> = self.fields_accessor.as_ref().unwrap().as_ref()();
65 fields
66 }
67
68 pub fn get_types(&self) -> Vec<&'static str> {
70 let types: Vec<&'static str> = self.types_accessor.as_ref().unwrap().as_ref()();
71 types
72 }
73}
74
75pub struct PacketRegistry {
77
78 pub keys: HashMap<String, PacketWrapper>,
80}
81
82impl PacketRegistry {
84
85 pub fn new() -> Self {
87 Self {
88 keys: HashMap::new()
89 }
90 }
91
92 pub fn register(&mut self, name: String, wrapper: PacketWrapper) {
94 self.keys.insert(name, wrapper);
95 }
96
97 pub fn get(&self, key: &str) -> &PacketWrapper {
98 &self.keys[key]
99 }
100}
101
102#[macro_export]
103macro_rules! is_type {
104 ($packet:ident, $packet_type:ident) => {{
105 $packet.as_any().is::<$packet_type>()
106 }}
107}
108
109#[macro_export]
110macro_rules! register_packet {
111 ($registry:ident, $packet:ident) => {{
112 $packet::register(&mut $registry);
113 }}
114}
115
116#[macro_export]
117macro_rules! register_packet_ref {
118 ($registry:ident, $packet:ident) => {{
119 $packet::register($registry);
120 }}
121}
122
123#[macro_export]
124macro_rules! cast_packet {
125 ($exp:ident as $ty:ty) => {{
126 let casted = $exp.as_any().downcast_ref::<$ty>().unwrap().clone();
127 casted
128 }}
129}
130
131#[macro_export]
132macro_rules! packet_data {
133 ($($exp:expr),*) => {{
134 let vec: Vec<Box<dyn std::any::Any>> = vec![$(Box::new($exp)),*];
135 vec
136 }}
137}
138
139#[macro_export]
140macro_rules! packet {
156 (@jvm($jvmname:literal) $name:ident { $($fname:ident : $ftype:ty),* }) => {
157
158 #[derive(Clone)]
159 pub struct $name {
160 $(pub $fname : $ftype),*
161 }
162
163 impl sonet_rs::packet::Packet for $name {
164 fn as_any(&self) -> &dyn std::any::Any {
165 self
166 }
167
168 fn get_name(&self) -> &'static str {
169 $jvmname
170 }
171
172 fn object_field_names(&self) -> Vec<&'static str> {
173 vec![$(stringify!($fname)),*]
174 }
175
176 fn object_type_names(&self) -> Vec<&'static str> {
177 vec![$(stringify!($ftype)),*]
178 }
179
180 fn get_values(&self) -> Vec<Box<dyn std::any::Any>> {
181 let mut values: Vec<Box<dyn std::any::Any>> = vec![];
182
183 $(values.push(Box::new(self.$fname.clone()));)*
184
185 values
186 }
187 }
188
189 impl $name {
190
191 pub fn field_names() -> Vec<&'static str> {
192 vec![$(stringify!($fname)),*]
193 }
194
195 pub fn type_names() -> Vec<&'static str> {
196 vec![$(stringify!($ftype)),*]
197 }
198
199 pub fn new(vec: Vec<Box<dyn std::any::Any>>) -> Self {
200 let mut iterator = sonet_rs::util::JIterator::new(vec);
201 Self {
202 $($fname : (*iterator.next()).downcast_ref::<$ftype>().unwrap().to_owned() ),*
203 }
204 }
205
206 pub fn register(registry: &mut crate::packet::PacketRegistry) {
211 let wrapper = sonet_rs::packet::PacketWrapper::new(
212 Some(Box::new(||{
213 Self::field_names()
214 })),
215 Some(Box::new(|vec|{
216 Box::new(Self::new(vec))
217 })),
218 Some(Box::new(||{
219 Self::type_names()
220 })));
221
222 registry.register($jvmname.to_string(), wrapper);
223 }
224 }
225 };
226}