diff options
Diffstat (limited to 'p2p/src/protocol.rs')
| -rw-r--r-- | p2p/src/protocol.rs | 113 | 
1 files changed, 113 insertions, 0 deletions
| diff --git a/p2p/src/protocol.rs b/p2p/src/protocol.rs new file mode 100644 index 0000000..515efc6 --- /dev/null +++ b/p2p/src/protocol.rs @@ -0,0 +1,113 @@ +use std::sync::Arc; + +use async_trait::async_trait; + +use karyons_core::{event::EventValue, Executor}; + +use crate::{peer::ArcPeer, utils::Version, Result}; + +pub type ArcProtocol = Arc<dyn Protocol>; + +pub type ProtocolConstructor = dyn Fn(ArcPeer) -> Arc<dyn Protocol> + Send + Sync; + +pub type ProtocolID = String; + +/// Protocol event +#[derive(Debug, Clone)] +pub enum ProtocolEvent { +    /// Message event, contains a vector of bytes. +    Message(Vec<u8>), +    /// Shutdown event signals the protocol to gracefully shut down. +    Shutdown, +} + +impl EventValue for ProtocolEvent { +    fn id() -> &'static str { +        "ProtocolEvent" +    } +} + +/// The Protocol trait defines the interface for core protocols +/// and custom protocols. +/// +/// # Example +/// ``` +/// use std::sync::Arc; +/// +/// use async_trait::async_trait; +/// use smol::Executor; +/// +/// use karyons_p2p::{ +///     protocol::{ArcProtocol, Protocol, ProtocolID, ProtocolEvent}, +///     Backend, PeerID, Config, Version, P2pError, ArcPeer}; +/// +/// pub struct NewProtocol { +///     peer: ArcPeer, +/// } +/// +/// impl NewProtocol { +///     fn new(peer: ArcPeer) -> ArcProtocol { +///         Arc::new(Self { +///             peer, +///         }) +///     } +/// } +/// +/// #[async_trait] +/// impl Protocol for NewProtocol { +///     async fn start(self: Arc<Self>, ex: Arc<Executor<'_>>) -> Result<(), P2pError> { +///         let listener = self.peer.register_listener::<Self>().await; +///         loop { +///             let event = listener.recv().await.unwrap(); +/// +///             match event { +///                 ProtocolEvent::Message(msg) => { +///                     println!("{:?}", msg); +///                 } +///                 ProtocolEvent::Shutdown => { +///                     break; +///                 } +///             } +///         } +/// +///         listener.cancel().await; +///         Ok(()) +///     } +/// +///     fn version() -> Result<Version, P2pError> { +///         "0.2.0, >0.1.0".parse() +///     } +/// +///     fn id() -> ProtocolID { +///         "NEWPROTOCOLID".into() +///     } +/// } +/// +///  async { +///     let peer_id = PeerID::random(); +///     let config = Config::default(); +/// +///     // Create a new Backend +///     let backend = Backend::new(peer_id, config); +/// +///     // Attach the NewProtocol +///     let c = move |peer| NewProtocol::new(peer); +///     backend.attach_protocol::<NewProtocol>(c).await.unwrap(); +///  }; +/// +/// ```   +#[async_trait] +pub trait Protocol: Send + Sync { +    /// Start the protocol +    async fn start(self: Arc<Self>, ex: Executor<'_>) -> Result<()>; + +    /// Returns the version of the protocol. +    fn version() -> Result<Version> +    where +        Self: Sized; + +    /// Returns the unique ProtocolID associated with the protocol. +    fn id() -> ProtocolID +    where +        Self: Sized; +} | 
