1#![warn(
2 clippy::all,
3 clippy::todo,
4 clippy::empty_enum,
5 clippy::mem_forget,
6 clippy::unused_self,
7 clippy::filter_map_next,
8 clippy::needless_continue,
9 clippy::needless_borrow,
10 clippy::match_wildcard_for_single_variants,
11 clippy::if_let_mutex,
12 clippy::await_holding_lock,
13 clippy::match_on_vec_items,
14 clippy::imprecise_flops,
15 clippy::suboptimal_flops,
16 clippy::lossy_float_literal,
17 clippy::rest_pat_in_fully_bound_structs,
18 clippy::fn_params_excessive_bools,
19 clippy::exit,
20 clippy::inefficient_to_string,
21 clippy::linkedlist,
22 clippy::macro_use_imports,
23 clippy::option_option,
24 clippy::verbose_file_reads,
25 clippy::unnested_or_patterns,
26 rust_2018_idioms,
27 rust_2024_compatibility,
28 future_incompatible,
29 nonstandard_style,
30 missing_docs
31)]
32
33pub mod adapter;
37pub mod packet;
38pub mod parser;
39
40use std::{collections::VecDeque, ops::Deref, str::FromStr};
41
42use bytes::Bytes;
43pub use engineioxide_core::{Sid, Str};
44use serde::{Deserialize, Serialize};
45
46#[derive(Clone, Serialize, Deserialize, Debug, Copy, PartialEq, Eq, Default)]
48pub struct Uid(Sid);
49impl Deref for Uid {
50 type Target = Sid;
51 fn deref(&self) -> &Self::Target {
52 &self.0
53 }
54}
55impl std::fmt::Display for Uid {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 self.0.fmt(f)
58 }
59}
60impl FromStr for Uid {
61 type Err = <Sid as FromStr>::Err;
62 fn from_str(s: &str) -> Result<Self, Self::Err> {
63 Ok(Self(Sid::from_str(s)?))
64 }
65}
66impl Uid {
67 pub const ZERO: Self = Self(Sid::ZERO);
69 pub fn new() -> Self {
71 Self(Sid::new())
72 }
73}
74
75#[derive(Debug, Clone, PartialEq)]
81pub enum Value {
82 Str(Str, Option<VecDeque<bytes::Bytes>>),
85 Bytes(bytes::Bytes),
87}
88
89impl Serialize for Value {
91 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
92 let raw = match self {
93 Value::Str(data, bins) => (0u8, data.as_bytes(), bins),
94 Value::Bytes(data) => (1u8, data.as_ref(), &None),
95 };
96 raw.serialize(serializer)
97 }
98}
99impl<'de> Deserialize<'de> for Value {
100 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
101 let (idx, data, bins): (u8, Vec<u8>, Option<VecDeque<Bytes>>) =
102 Deserialize::deserialize(deserializer)?;
103 let res = match idx {
104 0 => Value::Str(
105 Str::from(String::from_utf8(data).map_err(serde::de::Error::custom)?),
106 bins,
107 ),
108 1 => Value::Bytes(Bytes::from(data)),
109 i => Err(serde::de::Error::custom(format!(
110 "invalid value type: {}",
111 i
112 )))?,
113 };
114 Ok(res)
115 }
116}
117
118#[cfg(fuzzing)]
119#[doc(hidden)]
120impl arbitrary::Arbitrary<'_> for Value {
121 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
122 let res = match u.arbitrary::<bool>()? {
123 true => Value::Bytes(u.arbitrary::<Vec<u8>>()?.into()),
124 false => Value::Str(
125 u.arbitrary::<String>()?.into(),
126 Some(
127 u.arbitrary_iter::<Vec<u8>>()?
128 .filter_map(|b| b.ok().map(bytes::Bytes::from))
129 .collect(),
130 ),
131 ),
132 };
133 Ok(res)
134 }
135}
136
137impl Value {
138 pub fn as_str(&self) -> Option<&Str> {
140 match self {
141 Value::Str(data, _) => Some(data),
142 Value::Bytes(_) => None,
143 }
144 }
145 pub fn as_bytes(&self) -> Option<&bytes::Bytes> {
147 match self {
148 Value::Str(_, _) => None,
149 Value::Bytes(data) => Some(data),
150 }
151 }
152 pub fn len(&self) -> usize {
154 match self {
155 Value::Str(data, _) => data.len(),
156 Value::Bytes(data) => data.len(),
157 }
158 }
159 pub fn is_empty(&self) -> bool {
161 self.len() == 0
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::{Str, Value};
168 use bytes::Bytes;
169 use std::collections::VecDeque;
170
171 fn assert_serde_value(value: Value) {
172 let serialized = serde_json::to_string(&value).unwrap();
173 let deserialized: Value = serde_json::from_str(&serialized).unwrap();
174
175 assert_eq!(value, deserialized);
176 }
177
178 #[test]
179 fn value_serde_str_with_bins() {
180 let mut bins = VecDeque::new();
181 bins.push_back(Bytes::from_static(&[1, 2, 3, 4]));
182 bins.push_back(Bytes::from_static(&[5, 6, 7, 8]));
183
184 let value = Value::Str(Str::from("value".to_string()), Some(bins));
185 assert_serde_value(value);
186 }
187
188 #[test]
189 fn value_serde_bytes() {
190 let value = Value::Bytes(Bytes::from_static(&[1, 2, 3, 4]));
191 assert_serde_value(value);
192 }
193
194 #[test]
195 fn value_serde_str_without_bins() {
196 let value = Value::Str(Str::from("value_no_bins".to_string()), None);
197 assert_serde_value(value);
198 }
199
200 #[test]
201 fn value_serde_invalid_type() {
202 let invalid_data = "[2, [1,2,3,4], null]";
203 let result: Result<Value, _> = serde_json::from_str(invalid_data);
204 assert!(result.is_err());
205 }
206}