Skip to content

Commit

Permalink
Rename constructors to better support type aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaseizinger committed May 23, 2023
1 parent 4122c4e commit 74669a3
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 113 deletions.
2 changes: 1 addition & 1 deletion examples/file-sharing/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub(crate) async fn new(
transport,
ComposedBehaviour {
kademlia: Kademlia::new(peer_id, MemoryStore::new(peer_id)),
request_response: request_response::Behaviour::new(
request_response: request_response::Behaviour::with_codec(
FileExchangeCodec(),
iter::once((
StreamProtocol::new("/file-exchange/1"),
Expand Down
2 changes: 1 addition & 1 deletion protocols/autonat/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl Behaviour {
let protocols = iter::once((DEFAULT_PROTOCOL_NAME, ProtocolSupport::Full));
let mut cfg = request_response::Config::default();
cfg.set_request_timeout(config.timeout);
let inner = request_response::Behaviour::new(AutoNatCodec, protocols, cfg);
let inner = request_response::Behaviour::with_codec(AutoNatCodec, protocols, cfg);
Self {
local_peer_id,
inner,
Expand Down
1 change: 1 addition & 0 deletions protocols/request-response/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 0.25.0 - unreleased

- Add `request_response::json::Behaviour` and `request_response::cbor::Behaviour` building on top of the `serde` traits.
To conveniently construct these, we remove the `Codec` parameter from `Behaviour::new` and add `Behaviour::with_codec`.
See [PR 3952].

- Raise MSRV to 1.65.
Expand Down
80 changes: 31 additions & 49 deletions protocols/request-response/src/cbor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,29 @@ use libp2p_swarm::NetworkBehaviour;
use serde::{de::DeserializeOwned, Serialize};
use std::ops::Deref;

pub type OutEvent<Req, Resp> = crate::Event<Req, Resp>;

#[derive(NetworkBehaviour)]
#[behaviour(
to_swarm = "OutEvent<Req, Resp>",
prelude = "libp2p_swarm::derive_prelude"
)]
pub struct Behaviour<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned + 'static,
Resp: Send + Clone + Serialize + DeserializeOwned + 'static,
{
inner: crate::Behaviour<codec::Codec<Req, Resp>>,
}

impl<Req, Resp> Behaviour<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned,
Resp: Send + Clone + Serialize + DeserializeOwned,
{
pub fn new<I>(protocols: I, cfg: Config) -> Self
where
I: IntoIterator<
Item = (
<codec::Codec<Req, Resp> as crate::Codec>::Protocol,
ProtocolSupport,
),
>,
{
Behaviour {
inner: crate::Behaviour::new(codec::Codec::default(), protocols, cfg),
}
}
}

impl<Req, Resp> Deref for Behaviour<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned,
Resp: Send + Clone + Serialize + DeserializeOwned,
{
type Target = crate::Behaviour<codec::Codec<Req, Resp>>;

fn deref(&self) -> &Self::Target {
&self.inner
}
}
/// A request-response behaviour using [`serde_cbor`] for serializing and deserializing the messages.
///
/// # Example
///
/// ```
/// # use libp2p_request_response::{cbor, ProtocolSupport, self as request_response};
/// # use libp2p_swarm::{StreamProtocol, SwarmBuilder};
/// #[derive(Debug, serde::Serialize, serde::Deserialize)]
/// struct GreetRequest {
/// name: String,
/// }
///
/// #[derive(Debug, serde::Serialize, serde::Deserialize)]
/// struct GreetResponse {
/// message: String,
/// }
///
/// let behaviour = cbor::Behaviour::<GreetRequest, GreetResponse>::new(
/// [(StreamProtocol::new("/my-cbor-protocol"), ProtocolSupport::Full)],
/// request_response::Config::default()
/// );
/// ```
pub type Behaviour<Req, Resp> = crate::Behaviour<codec::Codec<Req, Resp>>;

mod codec {
use async_trait::async_trait;
Expand All @@ -84,7 +61,6 @@ mod codec {
/// Max response size in bytes
const RESPONSE_SIZE_MAXIMUM: usize = 10 * 1024 * 1024;

#[derive(Debug, Clone)]
pub struct Codec<Req, Resp> {
phantom: PhantomData<(Req, Resp)>,
}
Expand All @@ -97,11 +73,17 @@ mod codec {
}
}

impl<Req, Resp> Clone for Codec<Req, Resp> {
fn clone(&self) -> Self {
Self::default()
}
}

#[async_trait]
impl<Req, Resp> crate::Codec for Codec<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned,
Resp: Send + Clone + Serialize + DeserializeOwned,
Req: Send + Serialize + DeserializeOwned,
Resp: Send + Serialize + DeserializeOwned,
{
type Protocol = StreamProtocol;
type Request = Req;
Expand Down
80 changes: 31 additions & 49 deletions protocols/request-response/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,29 @@ use libp2p_swarm::NetworkBehaviour;
use serde::{de::DeserializeOwned, Serialize};
use std::ops::Deref;

pub type OutEvent<Req, Resp> = crate::Event<Req, Resp>;

#[derive(NetworkBehaviour)]
#[behaviour(
to_swarm = "OutEvent<Req, Resp>",
prelude = "libp2p_swarm::derive_prelude"
)]
pub struct Behaviour<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned + 'static,
Resp: Send + Clone + Serialize + DeserializeOwned + 'static,
{
inner: crate::Behaviour<codec::Codec<Req, Resp>>,
}

impl<Req, Resp> Behaviour<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned,
Resp: Send + Clone + Serialize + DeserializeOwned,
{
pub fn new<I>(protocols: I, cfg: Config) -> Self
where
I: IntoIterator<
Item = (
<codec::Codec<Req, Resp> as crate::Codec>::Protocol,
ProtocolSupport,
),
>,
{
Behaviour {
inner: crate::Behaviour::new(codec::Codec::default(), protocols, cfg),
}
}
}

impl<Req, Resp> Deref for Behaviour<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned,
Resp: Send + Clone + Serialize + DeserializeOwned,
{
type Target = crate::Behaviour<codec::Codec<Req, Resp>>;

fn deref(&self) -> &Self::Target {
&self.inner
}
}
/// A request-response behaviour using [`serde_json`] for serializing and deserializing the messages.
///
/// # Example
///
/// ```
/// # use libp2p_request_response::{json, ProtocolSupport, self as request_response};
/// # use libp2p_swarm::{StreamProtocol};
/// #[derive(Debug, serde::Serialize, serde::Deserialize)]
/// struct GreetRequest {
/// name: String,
/// }
///
/// #[derive(Debug, serde::Serialize, serde::Deserialize)]
/// struct GreetResponse {
/// message: String,
/// }
///
/// let behaviour = json::Behaviour::<GreetRequest, GreetResponse>::new(
/// [(StreamProtocol::new("/my-json-protocol"), ProtocolSupport::Full)],
/// request_response::Config::default()
/// );
/// ```
pub type Behaviour<Req, Resp> = crate::Behaviour<codec::Codec<Req, Resp>>;

mod codec {
use async_trait::async_trait;
Expand All @@ -84,7 +61,6 @@ mod codec {
/// Max response size in bytes
const RESPONSE_SIZE_MAXIMUM: usize = 10 * 1024 * 1024;

#[derive(Debug, Clone)]
pub struct Codec<Req, Resp> {
phantom: PhantomData<(Req, Resp)>,
}
Expand All @@ -97,11 +73,17 @@ mod codec {
}
}

impl<Req, Resp> Clone for Codec<Req, Resp> {
fn clone(&self) -> Self {
Self::default()
}
}

#[async_trait]
impl<Req, Resp> crate::Codec for Codec<Req, Resp>
where
Req: Send + Clone + Serialize + DeserializeOwned,
Resp: Send + Clone + Serialize + DeserializeOwned,
Req: Send + Serialize + DeserializeOwned,
Resp: Send + Serialize + DeserializeOwned,
{
type Protocol = StreamProtocol;
type Request = Req;
Expand Down
25 changes: 23 additions & 2 deletions protocols/request-response/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//! over the actual messages being sent, which are defined in terms of a
//! [`Codec`]. Creating a request/response protocol thus amounts
//! to providing an implementation of this trait which can then be
//! given to [`Behaviour::new`]. Further configuration options are
//! given to [`Behaviour::with_codec`]. Further configuration options are
//! available via the [`Config`].
//!
//! Requests are sent using [`Behaviour::send_request`] and the
Expand All @@ -39,6 +39,14 @@
//! receiving a [`Message::Request`] via
//! [`Event::Message`].
//!
//! ## Predefined codecs
//!
//! In case your message types implement [`serde::Serialize`] and [`serde::Deserialize`],
//! you can use two predefined behaviours:
//!
//! - [`cbor::Behaviour`] for CBOR-encoded messages
//! - [`json::Behaviour`] for JSON-encoded messages
//!
//! ## Protocol Families
//!
//! A single [`Behaviour`] instance can be used with an entire
Expand Down Expand Up @@ -332,13 +340,26 @@ where
pending_outbound_requests: HashMap<PeerId, SmallVec<[RequestProtocol<TCodec>; 10]>>,
}

impl<TCodec> Behaviour<TCodec>
where
TCodec: Codec + Default + Clone + Send + 'static,
{
/// Creates a new `Behaviour` for the given protocols and configuration, using [`Default`] to construct the codec.
pub fn new<I>(protocols: I, cfg: Config) -> Self
where
I: IntoIterator<Item = (TCodec::Protocol, ProtocolSupport)>,
{
Self::with_codec(TCodec::default(), protocols, cfg)
}
}

impl<TCodec> Behaviour<TCodec>
where
TCodec: Codec + Clone + Send + 'static,
{
/// Creates a new `Behaviour` for the given
/// protocols, codec and configuration.
pub fn new<I>(codec: TCodec, protocols: I, cfg: Config) -> Self
pub fn with_codec<I>(codec: TCodec, protocols: I, cfg: Config) -> Self
where
I: IntoIterator<Item = (TCodec::Protocol, ProtocolSupport)>,
{
Expand Down
26 changes: 15 additions & 11 deletions protocols/request-response/tests/ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ async fn is_response_outbound() {
));
let cfg = request_response::Config::default();

let mut swarm1 =
Swarm::new_ephemeral(|_| request_response::Behaviour::new(PingCodec(), protocols, cfg));
let mut swarm1 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::with_codec(PingCodec(), protocols, cfg)
});

let request_id1 = swarm1
.behaviour_mut()
Expand Down Expand Up @@ -87,11 +88,12 @@ async fn ping_protocol() {
let cfg = request_response::Config::default();

let mut swarm1 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::new(PingCodec(), protocols.clone(), cfg.clone())
request_response::Behaviour::with_codec(PingCodec(), protocols.clone(), cfg.clone())
});
let peer1_id = *swarm1.local_peer_id();
let mut swarm2 =
Swarm::new_ephemeral(|_| request_response::Behaviour::new(PingCodec(), protocols, cfg));
let mut swarm2 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::with_codec(PingCodec(), protocols, cfg)
});
let peer2_id = *swarm2.local_peer_id();

swarm1.listen().await;
Expand Down Expand Up @@ -178,11 +180,12 @@ async fn emits_inbound_connection_closed_failure() {
let cfg = request_response::Config::default();

let mut swarm1 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::new(PingCodec(), protocols.clone(), cfg.clone())
request_response::Behaviour::with_codec(PingCodec(), protocols.clone(), cfg.clone())
});
let peer1_id = *swarm1.local_peer_id();
let mut swarm2 =
Swarm::new_ephemeral(|_| request_response::Behaviour::new(PingCodec(), protocols, cfg));
let mut swarm2 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::with_codec(PingCodec(), protocols, cfg)
});
let peer2_id = *swarm2.local_peer_id();

swarm1.listen().await;
Expand Down Expand Up @@ -241,11 +244,12 @@ async fn emits_inbound_connection_closed_if_channel_is_dropped() {
let cfg = request_response::Config::default();

let mut swarm1 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::new(PingCodec(), protocols.clone(), cfg.clone())
request_response::Behaviour::with_codec(PingCodec(), protocols.clone(), cfg.clone())
});
let peer1_id = *swarm1.local_peer_id();
let mut swarm2 =
Swarm::new_ephemeral(|_| request_response::Behaviour::new(PingCodec(), protocols, cfg));
let mut swarm2 = Swarm::new_ephemeral(|_| {
request_response::Behaviour::with_codec(PingCodec(), protocols, cfg)
});
let peer2_id = *swarm2.local_peer_id();

swarm1.listen().await;
Expand Down

0 comments on commit 74669a3

Please sign in to comment.