Skip to content

Commit dad2880

Browse files
committed
feat!: use result instead of unwrap
# Breaking changes: - emit/emit_json functions switch from taking ownership and returning Emitter to taking mutable ref returning a result of an empty tuple
1 parent e96dc0f commit dad2880

4 files changed

Lines changed: 66 additions & 32 deletions

File tree

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ serde = "1.0"
1818
serde_json = "1.0"
1919
serde_derive = "1.0"
2020
rmp-serde = { version = "1.3", optional = true }
21+
thiserror = "1"
2122

2223
[dev-dependencies]
2324
testcontainers = { version = "0.22.0", features = ["blocking"] }
@@ -32,3 +33,7 @@ default = ["js-v7"]
3233
js-v7 = ["rmp-serde"]
3334
# Compatible with python-socketio v4 (socket.io protocol version 3 or 4)
3435
python-v4 = []
36+
37+
[lints.clippy]
38+
unwrap_in_result = "deny"
39+
unwrap_used = "deny"

src/implementations/javascript.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashMap;
22

3-
use crate::Emitter;
3+
use crate::{Emitter, Result};
44
use redis::Commands;
55
use rmp_serde::Serializer;
66
use serde::Serialize;
@@ -41,7 +41,7 @@ impl Emitter {
4141
self
4242
}
4343

44-
pub fn emit(mut self, message: Vec<&str>) -> Emitter {
44+
pub fn emit(&mut self, message: Vec<&str>) -> Result<()> {
4545
let packet = Packet {
4646
_type: 2,
4747
data: message.iter().map(|s| s.to_string()).collect(),
@@ -53,19 +53,18 @@ impl Emitter {
5353
};
5454
let mut msg = Vec::new();
5555
let val = (self.uid.clone(), packet, opts);
56-
val.serialize(&mut Serializer::new(&mut msg).with_struct_map())
57-
.unwrap();
56+
val.serialize(&mut Serializer::new(&mut msg).with_struct_map())?;
5857

5958
let channel = if self.rooms.len() == 1 {
6059
format!("{}{}#", self.channel, self.rooms.join("#"))
6160
} else {
6261
self.channel.clone()
6362
};
6463

65-
let _: () = self.redis.publish(channel, msg).unwrap();
64+
let _: () = self.redis.publish(channel, msg)?;
6665
self.rooms = vec![];
6766
self.flags = HashMap::new();
68-
self
67+
Ok(())
6968
}
7069
}
7170

src/implementations/python_socketio.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use redis::Commands;
44
use serde::Serialize;
55
use serde_json::json;
66

7-
use crate::Emitter;
7+
use crate::{Emitter, Result};
88

99
impl Emitter {
1010
/// Overrides the default channel name.
@@ -13,15 +13,19 @@ impl Emitter {
1313
self
1414
}
1515

16-
pub fn emit_json<T: Serialize, Event: Display>(mut self, event: Event, message: T) -> Emitter {
16+
pub fn emit_json<T: Serialize, Event: Display>(
17+
&mut self,
18+
event: Event,
19+
message: T,
20+
) -> Result<()> {
1721
fn _emit_json(
1822
redis: &mut redis::Client,
1923
channel: &str,
2024
nsp: &str,
2125
room: Option<&str>,
2226
event: &str,
2327
data: &serde_json::Value,
24-
) {
28+
) -> Result<()> {
2529
let message = json!({
2630
"method": "emit",
2731
"event": event,
@@ -32,10 +36,11 @@ impl Emitter {
3236
"callback": null,
3337
"host_id": null,
3438
});
35-
let _: () = redis.publish(channel, message.to_string()).unwrap();
39+
let _: () = redis.publish(channel, message.to_string())?;
40+
Ok(())
3641
}
3742
let event = event.to_string();
38-
let data = serde_json::to_value(&message).unwrap();
43+
let data = serde_json::to_value(&message)?;
3944

4045
if self.rooms.is_empty() {
4146
_emit_json(
@@ -45,7 +50,7 @@ impl Emitter {
4550
None,
4651
&event,
4752
&data,
48-
);
53+
)?;
4954
} else {
5055
for room in self.rooms.iter() {
5156
_emit_json(
@@ -55,10 +60,10 @@ impl Emitter {
5560
Some(&room),
5661
&event,
5762
&data,
58-
);
63+
)?;
5964
}
6065
}
61-
self
66+
Ok(())
6267
}
6368
}
6469

@@ -243,10 +248,11 @@ while True:
243248
#[test]
244249
fn test_emit_json() {
245250
let (redis, redis_url, container) = launch_containers(None);
246-
let emitter = Emitter::new(redis::Client::open(redis_url).unwrap());
251+
let emitter = Emitter::new(redis::Client::open(redis_url).unwrap()).unwrap();
247252
emitter
248253
.to("room")
249-
.emit_json("my_event", json!({"key": "value"}));
254+
.emit_json("my_event", json!({"key": "value"}))
255+
.unwrap();
250256
// Now check to see if the message was received
251257
let messages = PythonSocketIOImage::messages(&container);
252258
container.stop().unwrap();
@@ -264,10 +270,13 @@ while True:
264270
#[test]
265271
fn test_custom_channel() {
266272
let (redis, redis_url, container) = launch_containers(Some("custom_channel".to_string()));
267-
let emitter = Emitter::new(redis::Client::open(redis_url).unwrap()).channel("custom_channel");
273+
let emitter = Emitter::new(redis::Client::open(redis_url).unwrap())
274+
.unwrap()
275+
.channel("custom_channel");
268276
emitter
269277
.to("room")
270-
.emit_json("my_event", json!({"key": "value"}));
278+
.emit_json("my_event", json!({"key": "value"}))
279+
.unwrap();
271280
// Now check to see if the message was received
272281
let messages = PythonSocketIOImage::messages(&container);
273282
container.stop().unwrap();
@@ -285,8 +294,10 @@ while True:
285294
#[test]
286295
fn test_no_room() {
287296
let (redis, redis_url, container) = launch_containers(None);
288-
let emitter = Emitter::new(redis::Client::open(redis_url).unwrap());
289-
emitter.emit_json("my_event", json!({"key": "value"}));
297+
let mut emitter = Emitter::new(redis::Client::open(redis_url).unwrap()).unwrap();
298+
emitter
299+
.emit_json("my_event", json!({"key": "value"}))
300+
.unwrap();
290301
// Now check to see if the message was received
291302
let messages = PythonSocketIOImage::messages(&container);
292303
container.stop().unwrap();
@@ -304,8 +315,8 @@ while True:
304315
#[test]
305316
fn test_array_data() {
306317
let (redis, redis_url, container) = launch_containers(None);
307-
let emitter = Emitter::new(redis::Client::open(redis_url).unwrap());
308-
emitter.emit_json("my_event", json!([1, 2, 3]));
318+
let mut emitter = Emitter::new(redis::Client::open(redis_url).unwrap()).unwrap();
319+
emitter.emit_json("my_event", json!([1, 2, 3])).unwrap();
309320
// Now check to see if the message was received
310321
let messages = PythonSocketIOImage::messages(&container);
311322
container.stop().unwrap();

src/lib.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ extern crate serde_derive;
44
#[cfg(feature = "js-v7")]
55
use std::collections::HashMap;
66

7+
#[cfg(feature = "js-v7")]
8+
use std::collections::HashMap;
9+
710
mod implementations;
811

912
#[derive(Debug, Clone)]
@@ -28,31 +31,31 @@ pub struct EmitterOpts<'a> {
2831
}
2932

3033
pub trait IntoEmitter {
31-
fn into_emitter(self) -> Emitter;
34+
fn into_emitter(self) -> Result<Emitter>;
3235
}
3336

3437
impl IntoEmitter for redis::Client {
35-
fn into_emitter(self) -> Emitter {
36-
create_emitter(self, "socket.io", "/")
38+
fn into_emitter(self) -> Result<Emitter> {
39+
Ok(create_emitter(self, "socket.io", "/"))
3740
}
3841
}
3942

4043
impl<'a> IntoEmitter for EmitterOpts<'a> {
41-
fn into_emitter(self) -> Emitter {
44+
fn into_emitter(self) -> Result<Emitter> {
4245
let addr = format!("redis://{}:{}", self.host, self.port);
4346
let prefix = self.key.unwrap_or("socket.io");
4447

45-
create_emitter(redis::Client::open(addr.as_str()).unwrap(), prefix, "/")
48+
Ok(create_emitter(redis::Client::open(addr.as_str())?, prefix, "/"))
4649
}
4750
}
4851

4952
impl IntoEmitter for &str {
50-
fn into_emitter(self) -> Emitter {
51-
create_emitter(
52-
redis::Client::open(format!("redis://{}", self).as_str()).unwrap(),
53+
fn into_emitter(self) -> Result<Emitter> {
54+
Ok(create_emitter(
55+
redis::Client::open(format!("redis://{}", self).as_str())?,
5356
"socket.io",
5457
"/",
55-
)
58+
))
5659
}
5760
}
5861

@@ -74,7 +77,7 @@ fn create_emitter(redis: redis::Client, prefix: &str, nsp: &str) -> Emitter {
7477
}
7578

7679
impl Emitter {
77-
pub fn new<I: IntoEmitter>(data: I) -> Emitter {
80+
pub fn new<I: IntoEmitter>(data: I) -> Result<Emitter> {
7881
data.into_emitter()
7982
}
8083

@@ -96,6 +99,22 @@ compile_error!("At least one of the features 'js-v7' or 'python-v4' must be enab
9699
#[cfg(all(feature = "js-v7", feature = "python-v4"))]
97100
compile_error!("Only one of the features 'js-v7' or 'python-v4' can be enabled.");
98101

102+
#[non_exhaustive]
103+
#[derive(Debug, thiserror::Error)]
104+
pub enum Error {
105+
#[error("Error connecting to Redis: {0}")]
106+
Redis(#[from] redis::RedisError),
107+
#[error("Error serializing data: {0}")]
108+
#[cfg(feature = "python-v4")]
109+
Serde(#[from] serde_json::Error),
110+
#[error("Error serializing data: {0}")]
111+
#[cfg(feature = "js-v7")]
112+
Serde(#[from] rmp_serde::encode::Error),
113+
114+
}
115+
116+
pub type Result<T> = std::result::Result<T, Error>;
117+
99118
#[cfg(test)]
100119
pub(crate) mod tests {
101120
pub const DOCKER_NETWORK_NAME: &str = "testcontainers-socketio";

0 commit comments

Comments
 (0)