Skip to main content

asimov_protocol/
peer_connect.rs

1// This is free and unencumbered software released into the public domain.
2
3#![allow(dead_code)]
4
5use crate::{
6    ConnectError, Message, MessageRecv, MessageSend, PeerConnection, PeerHello, RecvError,
7    SendError, peer_connection_state::*,
8};
9use core::convert::Infallible;
10
11#[derive(Debug)]
12pub struct PeerConnect<State = Connected>(State);
13
14impl From<iroh::endpoint::Connection> for PeerConnect {
15    fn from(inner: iroh::endpoint::Connection) -> Self {
16        Self(Connected { inner })
17    }
18}
19
20impl PeerConnect<Connected> {
21    pub async fn send_hello(self) -> Result<PeerConnect<Negotiating>, ConnectError> {
22        let Connected { inner } = self.0;
23        let (send, recv) = inner.open_bi().await?;
24        let mut connection = PeerConnect(Negotiating { inner, send, recv });
25        let request = Message::Hello(PeerHello::default());
26        let _ = connection.send(request).await?;
27        Ok(connection)
28    }
29}
30
31impl PeerConnect<Negotiating> {
32    pub async fn recv_hello(mut self) -> Result<PeerConnect<Ready>, ConnectError> {
33        let response = self.recv().await?;
34        let Message::Hello(hello) = response else {
35            return Err(ConnectError::InvalidMessage(response));
36        };
37        let Negotiating { inner, send, recv } = self.0;
38        Ok(PeerConnect(Ready {
39            inner,
40            send,
41            recv,
42            hello,
43        }))
44    }
45}
46
47impl PeerConnect<Ready> {
48    pub fn hello(&self) -> &PeerHello {
49        return &self.0.hello;
50    }
51
52    pub fn close(self) -> Result<PeerConnect<Closed>, Infallible> {
53        let Ready { inner, .. } = self.0;
54        inner.close(0u32.into(), &[]);
55        Ok(PeerConnect(Closed { inner }))
56    }
57
58    pub fn into_connection(self) -> PeerConnection {
59        let Ready {
60            inner,
61            send,
62            recv,
63            hello,
64        } = self.0;
65        PeerConnection {
66            inner,
67            send,
68            recv,
69            hello,
70        }
71    }
72}
73
74impl MessageSend for PeerConnect<Negotiating> {
75    async fn write_all(&mut self, buffer: &[u8]) -> Result<(), SendError> {
76        Ok(self.0.send.write_all(buffer).await?)
77    }
78}
79
80impl MessageSend for PeerConnect<Ready> {
81    async fn write_all(&mut self, buffer: &[u8]) -> Result<(), SendError> {
82        Ok(self.0.send.write_all(buffer).await?)
83    }
84}
85
86impl MessageRecv for PeerConnect<Negotiating> {
87    async fn read_exact(&mut self, buffer: &mut [u8]) -> Result<(), RecvError> {
88        Ok(self.0.recv.read_exact(buffer).await?)
89    }
90}
91
92impl MessageRecv for PeerConnect<Ready> {
93    async fn read_exact(&mut self, buffer: &mut [u8]) -> Result<(), RecvError> {
94        Ok(self.0.recv.read_exact(buffer).await?)
95    }
96}