Skip to content

Commit

Permalink
Use Error trait from core
Browse files Browse the repository at this point in the history
This patch gets rid of the `anyhow` dependency in favor of
`core::error::Error` and sets the MSRV to 1.81.0
  • Loading branch information
caio committed Sep 5, 2024
1 parent 75c6bd8 commit f93b202
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 36 deletions.
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "foca"
version = "0.17.2"
rust-version = "1.70.0"
rust-version = "1.81.0"
authors = ["Caio <[email protected]>"]
edition = "2021"
license = "MPL-2.0"
Expand All @@ -20,7 +20,7 @@ all-features = true
default = []

# Adds compatibility with some types and traits
std = ["anyhow/std"]
std = []
# Exposes `BincodeCodec` a lean general-purpose std-only codec
bincode-codec = ["std", "serde", "bincode", "bytes/std"]
# Exposes `PostcardCodec`, a no_std-friendly codec
Expand All @@ -29,7 +29,6 @@ postcard-codec = ["serde", "postcard"]
[dependencies]
rand = { version = "0.8", default-features = false }
bytes = { version = "1", default-features = false }
anyhow = { version = "1", default-features = false }

serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
bincode = { version = "1", default-features = false, optional = true }
Expand Down
15 changes: 13 additions & 2 deletions examples/foca_insecure_udp_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,10 +546,21 @@ impl Handler {
}
}

#[derive(Debug)]
struct Msg(String);

impl core::fmt::Display for Msg {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}

impl core::error::Error for Msg {}

impl foca::BroadcastHandler<ID> for Handler {
type Key = BroadcastKey;

type Error = String;
type Error = Msg;

fn receive_item(
&mut self,
Expand All @@ -565,7 +576,7 @@ impl foca::BroadcastHandler<ID> for Handler {
let Broadcast { key, msg }: Broadcast = self
.opts
.deserialize_from(&mut reader)
.map_err(|err| format!("bad broadcast: {err}"))?;
.map_err(|err| Msg(format!("bad broadcast: {err}")))?;

let is_new_message = self
.messages
Expand Down
4 changes: 2 additions & 2 deletions src/broadcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use alloc::vec::Vec;
use core::{cmp::Ordering, fmt};
use core::cmp::Ordering;

use bytes::BufMut;

Expand All @@ -21,7 +21,7 @@ pub trait BroadcastHandler<T> {

/// The error type that `receive_item` may emit. Will be wrapped
/// by [`crate::Error::CustomBroadcast`].
type Error: fmt::Debug + fmt::Display + Send + Sync + 'static;
type Error: core::error::Error + Send + 'static;

/// Decodes a [`Self::Key`] from a buffer and either discards
/// it or tells Foca to persist and disseminate it.
Expand Down
8 changes: 5 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use core::fmt;

use alloc::boxed::Box;

#[derive(Debug)]
/// This type represents all possible errors operating a Foca instance.
pub enum Error {
Expand Down Expand Up @@ -63,17 +65,17 @@ pub enum Error {
/// codec.
///
/// Might have left Foca in a inconsistent state.
Encode(anyhow::Error),
Encode(Box<dyn core::error::Error + Send>),

/// Wraps [`crate::Codec`]'s `decode_*` failures.
///
/// Can happen during normal operation when receiving junk data.
Decode(anyhow::Error),
Decode(Box<dyn core::error::Error + Send>),

/// Wraps [`crate::BroadcastHandler`] failures.
///
/// Doesn't affect Foca's state.
CustomBroadcast(anyhow::Error),
CustomBroadcast(Box<dyn core::error::Error + Send>),

/// Configuration change not allowed.
///
Expand Down
69 changes: 43 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
)]

extern crate alloc;
use alloc::vec::Vec;
use alloc::{boxed::Box, vec::Vec};

#[cfg(feature = "std")]
extern crate std;
Expand Down Expand Up @@ -206,6 +206,7 @@ impl<T, C, RNG> Foca<T, C, RNG, NoCustomBroadcast>
where
T: Identity,
C: Codec<T>,
C::Error: core::error::Error + Send,
RNG: Rng,
{
/// Create a new Foca instance with custom broadcasts disabled.
Expand Down Expand Up @@ -233,17 +234,14 @@ where
}
}

// XXX Does it make sense to have different associated type restrictions
// based on a feature flag? Say: when using `std` we would enforce
// that `Codec::Error` and `BroadcastHandler::Error` both implement
// `std::error::Error`, thus instead of wrapping these errors via
// `anyhow::Error::msg` we can use `anyhow::Error::new`.
impl<T, C, RNG, B> Foca<T, C, RNG, B>
where
T: Identity,
C: Codec<T>,
C::Error: core::error::Error,
RNG: Rng,
B: BroadcastHandler<T>,
B::Error: core::error::Error + 'static,
{
/// Initialize a new Foca instance.
pub fn with_custom_broadcast(
Expand Down Expand Up @@ -589,8 +587,7 @@ where
if let Some(key) = self
.broadcast_handler
.receive_item(data, None)
.map_err(anyhow::Error::msg)
.map_err(Error::CustomBroadcast)?
.map_err(|e| Error::CustomBroadcast(Box::new(e)))?
{
self.custom_broadcasts.add_or_replace(
key,
Expand Down Expand Up @@ -878,8 +875,7 @@ where
let header = self
.codec
.decode_header(&mut data)
.map_err(anyhow::Error::msg)
.map_err(Error::Decode)?;
.map_err(|e| Error::Decode(Box::new(e)))?;

#[cfg(feature = "tracing")]
span.record("header", tracing::field::debug(&header));
Expand Down Expand Up @@ -918,8 +914,7 @@ where
self.member_buf.push(
self.codec
.decode_member(&mut data)
.map_err(anyhow::Error::msg)
.map_err(Error::Decode)?,
.map_err(|e| Error::Decode(Box::new(e)))?,
);
}
}
Expand Down Expand Up @@ -1097,8 +1092,7 @@ where
let mut buf = Vec::new();
self.codec
.encode_member(&member, &mut buf)
.map_err(anyhow::Error::msg)
.map_err(Error::Encode)?;
.map_err(|e| Error::Encode(Box::new(e)))?;

Ok(buf)
}
Expand Down Expand Up @@ -1306,8 +1300,7 @@ where
if let Some(key) = self
.broadcast_handler
.receive_item(pkt, sender)
.map_err(anyhow::Error::msg)
.map_err(Error::CustomBroadcast)?
.map_err(|e| Error::CustomBroadcast(Box::new(e)))?
{
#[cfg(feature = "tracing")]
tracing::trace!(len = pkt_len, "received broadcast item");
Expand Down Expand Up @@ -1434,8 +1427,7 @@ where
if let Err(err) = self
.codec
.encode_header(&header, &mut buf)
.map_err(anyhow::Error::msg)
.map_err(Error::Encode)
.map_err(|e| Error::Encode(Box::new(e)))
{
debug_assert_eq!(0, self.send_buf.capacity(), "send_buf modified while taken");
self.send_buf = buf.into_inner();
Expand Down Expand Up @@ -1681,8 +1673,7 @@ impl fmt::Display for BroadcastsDisabledError {
}
}

#[cfg(feature = "std")]
impl std::error::Error for BroadcastsDisabledError {}
impl core::error::Error for BroadcastsDisabledError {}

impl<T> BroadcastHandler<T> for NoCustomBroadcast {
type Key = &'static [u8];
Expand Down Expand Up @@ -1712,8 +1703,10 @@ impl<T, C, RNG, B> Foca<T, C, RNG, B>
where
T: Identity,
C: Codec<T>,
C::Error: core::error::Error,
RNG: rand::Rng,
B: BroadcastHandler<T>,
B::Error: core::error::Error + Send,
{
pub fn incarnation(&self) -> Incarnation {
self.incarnation
Expand Down Expand Up @@ -1872,6 +1865,8 @@ mod tests {
}
}

impl core::error::Error for UnitError {}

impl Codec<ID> for UnitErroringCodec {
type Error = UnitError;

Expand Down Expand Up @@ -1918,12 +1913,12 @@ mod tests {
let mut foca = Foca::new(ID::new(1), Config::simple(), rng(), UnitErroringCodec);

assert_eq!(
Err(Error::Encode(anyhow::Error::msg(UnitError))),
Err(Error::Encode(alloc::boxed::Box::new(UnitError))),
foca.announce(ID::new(2), NoopRuntime)
);

assert_eq!(
Err(Error::Decode(anyhow::Error::msg(UnitError))),
Err(Error::Decode(alloc::boxed::Box::new(UnitError))),
foca.handle_data(b"hue", NoopRuntime)
);
}
Expand Down Expand Up @@ -3425,9 +3420,9 @@ mod tests {
buf.get_u16()
}

fn from_bytes(mut src: impl Buf) -> core::result::Result<Self, &'static str> {
fn from_bytes(mut src: impl Buf) -> core::result::Result<Self, Msg> {
if src.remaining() < 10 {
Err("buffer too small")
Err(Msg("buffer too small"))
} else {
let mut data = [0u8; 10];
let mut buf = &mut data[..];
Expand Down Expand Up @@ -3458,10 +3453,21 @@ mod tests {
use alloc::collections::BTreeMap;
struct Handler(BTreeMap<u64, u16>);

#[derive(Debug)]
struct Msg(&'static str);

impl core::fmt::Display for Msg {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}

impl core::error::Error for Msg {}

impl BroadcastHandler<ID> for Handler {
type Key = VersionedKey;

type Error = &'static str;
type Error = Msg;

fn receive_item(
&mut self,
Expand Down Expand Up @@ -4349,10 +4355,21 @@ mod tests {
}
}

#[derive(Debug)]
struct Msg(&'static str);

impl core::fmt::Display for Msg {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}

impl core::error::Error for Msg {}

impl BroadcastHandler<ID> for DumbHandler {
type Key = GrowOnly;

type Error = &'static str;
type Error = Msg;

fn receive_item(
&mut self,
Expand Down
2 changes: 2 additions & 0 deletions src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ impl core::fmt::Display for BadCodecError {
}
}

impl core::error::Error for BadCodecError {}

impl BadCodec {
fn encode_header(
&self,
Expand Down

0 comments on commit f93b202

Please sign in to comment.