karyon_p2p/protocol.rs
1use std::sync::Arc;
2
3use async_trait::async_trait;
4
5use karyon_eventemitter::EventValue;
6
7use crate::{peer::Peer, version::Version, Result};
8
9pub type ProtocolConstructor = dyn Fn(Arc<Peer>) -> Arc<dyn Protocol> + Send + Sync;
10
11pub type ProtocolID = String;
12
13/// Protocol event
14#[derive(Debug, Clone, EventValue)]
15pub enum ProtocolEvent {
16 /// Message event, contains a vector of bytes.
17 Message(Vec<u8>),
18 /// Shutdown event signals the protocol to gracefully shut down.
19 Shutdown,
20}
21
22/// The Protocol trait defines the interface for core protocols
23/// and custom protocols.
24///
25/// # Example
26/// ```
27/// use std::sync::Arc;
28///
29/// use async_trait::async_trait;
30/// use smol::Executor;
31///
32/// use karyon_p2p::{
33/// protocol::{Protocol, ProtocolID, ProtocolEvent},
34/// Backend, PeerID, Config, Version, Error, Peer,
35/// keypair::{KeyPair, KeyPairType},
36/// };
37///
38/// pub struct NewProtocol {
39/// peer: Arc<Peer>,
40/// }
41///
42/// impl NewProtocol {
43/// fn new(peer: Arc<Peer>) -> Arc<dyn Protocol> {
44/// Arc::new(Self {
45/// peer,
46/// })
47/// }
48/// }
49///
50/// #[async_trait]
51/// impl Protocol for NewProtocol {
52/// async fn start(self: Arc<Self>) -> Result<(), Error> {
53/// loop {
54/// match self.peer.recv::<Self>().await.expect("Receive msg") {
55/// ProtocolEvent::Message(msg) => {
56/// println!("{:?}", msg);
57/// }
58/// ProtocolEvent::Shutdown => {
59/// break;
60/// }
61/// }
62/// }
63/// Ok(())
64/// }
65///
66/// fn version() -> Result<Version, Error> {
67/// "0.2.0, >0.1.0".parse()
68/// }
69///
70/// fn id() -> ProtocolID {
71/// "NEWPROTOCOLID".into()
72/// }
73/// }
74///
75/// async {
76/// let key_pair = KeyPair::generate(&KeyPairType::Ed25519);
77/// let config = Config::default();
78///
79/// // Create a new Executor
80/// let ex = Arc::new(Executor::new());
81///
82/// // Create a new Backend
83/// let backend = Backend::new(&key_pair, config, ex.into());
84///
85/// // Attach the NewProtocol
86/// let c = move |peer| NewProtocol::new(peer);
87/// backend.attach_protocol::<NewProtocol>(c).await.unwrap();
88/// };
89///
90/// ```
91#[async_trait]
92pub trait Protocol: Send + Sync {
93 /// Start the protocol
94 async fn start(self: Arc<Self>) -> Result<()>;
95
96 /// Returns the version of the protocol.
97 fn version() -> Result<Version>
98 where
99 Self: Sized;
100
101 /// Returns the unique ProtocolID associated with the protocol.
102 fn id() -> ProtocolID
103 where
104 Self: Sized;
105}
106
107#[async_trait]
108pub(crate) trait InitProtocol: Send + Sync {
109 type T;
110 /// Initialize the protocol
111 async fn init(self: Arc<Self>) -> Self::T;
112}