libp2p/builder/phase/
behaviour.rs1use std::{convert::Infallible, marker::PhantomData};
2
3use libp2p_swarm::NetworkBehaviour;
4
5use super::*;
6use crate::SwarmBuilder;
7
8pub struct BehaviourPhase<T, R> {
9 pub(crate) relay_behaviour: R,
10 pub(crate) transport: T,
11}
12
13#[cfg(feature = "relay")]
14impl<T, Provider> SwarmBuilder<Provider, BehaviourPhase<T, libp2p_relay::client::Behaviour>> {
15 pub fn with_behaviour<B, R: TryIntoBehaviour<B>>(
16 self,
17 constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R,
18 ) -> Result<SwarmBuilder<Provider, SwarmPhase<T, B>>, R::Error> {
19 Ok(SwarmBuilder {
20 phase: SwarmPhase {
21 behaviour: constructor(&self.keypair, self.phase.relay_behaviour)
22 .try_into_behaviour()?,
23 transport: self.phase.transport,
24 },
25 keypair: self.keypair,
26 phantom: PhantomData,
27 })
28 }
29}
30
31impl<T, Provider> SwarmBuilder<Provider, BehaviourPhase<T, NoRelayBehaviour>> {
32 pub fn with_behaviour<B, R: TryIntoBehaviour<B>>(
33 self,
34 constructor: impl FnOnce(&libp2p_identity::Keypair) -> R,
35 ) -> Result<SwarmBuilder<Provider, SwarmPhase<T, B>>, R::Error> {
36 let _ = self.phase.relay_behaviour;
38
39 Ok(SwarmBuilder {
40 phase: SwarmPhase {
41 behaviour: constructor(&self.keypair).try_into_behaviour()?,
42 transport: self.phase.transport,
43 },
44 keypair: self.keypair,
45 phantom: PhantomData,
46 })
47 }
48}
49
50pub trait TryIntoBehaviour<B>: private::Sealed<Self::Error> {
51 type Error;
52
53 fn try_into_behaviour(self) -> Result<B, Self::Error>;
54}
55
56impl<B> TryIntoBehaviour<B> for B
57where
58 B: NetworkBehaviour,
59{
60 type Error = Infallible;
61
62 fn try_into_behaviour(self) -> Result<B, Self::Error> {
63 Ok(self)
64 }
65}
66
67impl<B> TryIntoBehaviour<B> for Result<B, Box<dyn std::error::Error + Send + Sync>>
68where
69 B: NetworkBehaviour,
70{
71 type Error = BehaviourError;
72
73 fn try_into_behaviour(self) -> Result<B, Self::Error> {
74 self.map_err(BehaviourError)
75 }
76}
77
78mod private {
79 pub trait Sealed<Error> {}
80}
81
82impl<B: NetworkBehaviour> private::Sealed<Infallible> for B {}
83
84impl<B: NetworkBehaviour> private::Sealed<BehaviourError>
85 for Result<B, Box<dyn std::error::Error + Send + Sync>>
86{
87}
88
89#[derive(Debug, thiserror::Error)]
90#[error("failed to build behaviour: {0}")]
91pub struct BehaviourError(Box<dyn std::error::Error + Send + Sync + 'static>);