Skip to content

Commit 9d0369f

Browse files
committed
Stop circumventing the std definition of FromUtf8Error
By already taking the `Vec<u8>` out of this error we leave users no choice to bubble up the error with typical `?` or `anyhow::Context::context()`, because `vec<u8>` does not implement `std::error::Error` (it's not an error after all). Instead of trying to outsmart the standard library and annoying the user, return the original `FromUtf8Error` *as it is*, leaving the caller to deal with it however they please (i.e. bubble it up, or call `into_bytes()` themselves if they wish to continue parsing it otherwise).
1 parent 7ffd6c8 commit 9d0369f

File tree

4 files changed

+25
-16
lines changed

4 files changed

+25
-16
lines changed

src/lib.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -750,11 +750,10 @@ impl Socket {
750750

751751
/// Receive a `String` from the socket.
752752
///
753-
/// If the received message is not valid UTF-8, it is returned as the original
754-
/// Vec in the `Err` part of the inner result.
755-
pub fn recv_string(&self, flags: i32) -> Result<result::Result<String, Vec<u8>>> {
756-
self.recv_bytes(flags)
757-
.map(|bytes| String::from_utf8(bytes).map_err(FromUtf8Error::into_bytes))
753+
/// If the received message is not valid UTF-8, a [`FromUtf8Error`] is returned and the original
754+
/// bytes can be retrieved via [`FromUtf8Error::into_bytes()`].
755+
pub fn recv_string(&self, flags: i32) -> Result<result::Result<String, FromUtf8Error>> {
756+
self.recv_bytes(flags).map(String::from_utf8)
758757
}
759758

760759
/// Receive a multipart message from the socket.
@@ -885,7 +884,7 @@ impl Socket {
885884
sockopt::get_bytes(self.sock, zmq_sys::ZMQ_ROUTING_ID as c_int, 255)
886885
}
887886

888-
pub fn get_socks_proxy(&self) -> Result<result::Result<String, Vec<u8>>> {
887+
pub fn get_socks_proxy(&self) -> Result<result::Result<String, FromUtf8Error>> {
889888
// 255 = longest allowable domain name is 253 so this should
890889
// be a reasonable size.
891890
sockopt::get_string(self.sock, zmq_sys::ZMQ_SOCKS_PROXY as c_int, 255, true)
@@ -901,17 +900,17 @@ impl Socket {
901900
})
902901
}
903902

904-
pub fn get_plain_username(&self) -> Result<result::Result<String, Vec<u8>>> {
903+
pub fn get_plain_username(&self) -> Result<result::Result<String, FromUtf8Error>> {
905904
// 255 = arbitrary size
906905
sockopt::get_string(self.sock, zmq_sys::ZMQ_PLAIN_USERNAME as c_int, 255, true)
907906
}
908907

909-
pub fn get_plain_password(&self) -> Result<result::Result<String, Vec<u8>>> {
908+
pub fn get_plain_password(&self) -> Result<result::Result<String, FromUtf8Error>> {
910909
// 256 = arbitrary size based on std crypto key size
911910
sockopt::get_string(self.sock, zmq_sys::ZMQ_PLAIN_PASSWORD as c_int, 256, true)
912911
}
913912

914-
pub fn get_zap_domain(&self) -> Result<result::Result<String, Vec<u8>>> {
913+
pub fn get_zap_domain(&self) -> Result<result::Result<String, FromUtf8Error>> {
915914
// 255 = arbitrary size
916915
sockopt::get_string(self.sock, zmq_sys::ZMQ_ZAP_DOMAIN as c_int, 255, true)
917916
}
@@ -924,7 +923,7 @@ impl Socket {
924923
/// used with the wildcard address (`"*"`), in the address
925924
/// returned, the wildcard will be expanded into the any address
926925
/// (i.e. `0.0.0.0` with IPv4).
927-
pub fn get_last_endpoint(&self) -> Result<result::Result<String, Vec<u8>>> {
926+
pub fn get_last_endpoint(&self) -> Result<result::Result<String, FromUtf8Error>> {
928927
// 256 + 9 + 1 = maximum inproc name size (= 256) + "inproc://".len() (= 9), plus null byte
929928
sockopt::get_string(
930929
self.sock,
@@ -962,12 +961,12 @@ impl Socket {
962961
sockopt::get_bytes(self.sock, zmq_sys::ZMQ_CURVE_SERVERKEY as c_int, 32)
963962
}
964963

965-
pub fn get_gssapi_principal(&self) -> Result<result::Result<String, Vec<u8>>> {
964+
pub fn get_gssapi_principal(&self) -> Result<result::Result<String, FromUtf8Error>> {
966965
// 260 = best guess of max length based on docs.
967966
sockopt::get_string(self.sock, zmq_sys::ZMQ_GSSAPI_PRINCIPAL as c_int, 260, true)
968967
}
969968

970-
pub fn get_gssapi_service_principal(&self) -> Result<result::Result<String, Vec<u8>>> {
969+
pub fn get_gssapi_service_principal(&self) -> Result<result::Result<String, FromUtf8Error>> {
971970
// 260 = best guess of max length based on docs.
972971
sockopt::get_string(
973972
self.sock,

src/sockopt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ pub fn get_string(
6363
opt: c_int,
6464
size: size_t,
6565
remove_nulbyte: bool,
66-
) -> Result<result::Result<String, Vec<u8>>> {
66+
) -> Result<result::Result<String, FromUtf8Error>> {
6767
let mut value = get_bytes(sock, opt, size)?;
6868

6969
if remove_nulbyte {
7070
value.pop();
7171
}
72-
Ok(String::from_utf8(value).map_err(FromUtf8Error::into_bytes))
72+
Ok(String::from_utf8(value))
7373
}
7474

7575
macro_rules! setsockopt_num(

tests/compile-fail/socket-thread-unsafe.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ error[E0277]: `*mut c_void` cannot be shared between threads safely
99
15 | | });
1010
| |_____^ `*mut c_void` cannot be shared between threads safely
1111
|
12-
= help: within `Socket`, the trait `Sync` is not implemented for `*mut c_void`, which is required by `{closure@$DIR/tests/compile-fail/socket-thread-unsafe.rs:13:27: 13:34}: Send`
12+
= help: within `Socket`, the trait `Sync` is not implemented for `*mut c_void`
1313
note: required because it appears within the type `Socket`
1414
--> src/lib.rs
1515
|
@@ -23,3 +23,9 @@ note: required because it's used within this closure
2323
| ^^^^^^^
2424
note: required by a bound in `spawn`
2525
--> $RUST/std/src/thread/mod.rs
26+
|
27+
| pub fn spawn<F, T>(f: F) -> JoinHandle<T>
28+
| ----- required by a bound in this function
29+
...
30+
| F: Send + 'static,
31+
| ^^^^ required by this bound in `spawn`

tests/test.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod common;
33

44
use std::io;
55
use std::net::TcpStream;
6+
use std::string::FromUtf8Error;
67
use zmq::*;
78

89
fn version_ge_4_2() -> bool {
@@ -64,7 +65,10 @@ test!(test_exchanging_strings, {
6465
// non-UTF8 strings -> get an Err with bytes when receiving
6566
receiver.send(b"\xff\xb7".as_ref(), 0).unwrap();
6667
let result = sender.recv_string(0).unwrap();
67-
assert_eq!(result, Err(vec![0xff, 0xb7]));
68+
assert_eq!(
69+
result.map_err(FromUtf8Error::into_bytes),
70+
Err(vec![0xff, 0xb7])
71+
);
6872
});
6973

7074
test!(test_exchanging_multipart, {

0 commit comments

Comments
 (0)