1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
#[macro_use] extern crate serde_derive; #[macro_use] extern crate log; pub mod find_service; mod framing; pub mod publisher; pub mod subscriber; use find_service::proto; use std::fmt; use std::io; use std::net::{SocketAddr, ToSocketAddrs}; use std::time; use tokio::{net::UdpSocket, sync::oneshot::error::RecvError as OneshotRecvError, time as timer}; #[derive(Debug)] pub enum Error { Empty, AddrParseError, IoError(io::Error), FramingError(framing::Error), TimerError(timer::Error), OneshotError(OneshotRecvError), } type DataGram = (framing::Message, SocketAddr); type Generation = u64; pub const MAX_DATA_SIZE: usize = 1024; impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { match self { Error::Empty => write!(f, "Empty Error"), Error::IoError(e) => write!(f, "IO Error: {}", e), Error::FramingError(e) => write!(f, "Framing Error: {}", e), Error::AddrParseError => write!(f, "Error Parsing Address"), Error::TimerError(e) => write!(f, "Error in tokio timer: {}", e), Error::OneshotError(e) => write!(f, "Error in internal messaging:{}", e), } } } impl std::error::Error for Error {} impl From<()> for Error { fn from(_err: ()) -> Error { Error::Empty } } impl From<io::Error> for Error { fn from(err: io::Error) -> Error { Error::IoError(err) } } impl From<framing::Error> for Error { fn from(err: framing::Error) -> Error { Error::FramingError(err) } } impl From<timer::Error> for Error { fn from(err: timer::Error) -> Error { Error::TimerError(err) } } impl From<OneshotRecvError> for Error { fn from(err: OneshotRecvError) -> Error { Error::OneshotError(err) } } type Result<T> = std::result::Result<T, Error>; #[derive(Serialize, Deserialize, Clone, Debug)] pub struct PublisherDesc { pub name: String, pub host_name: String, pub port: u16, pub subscriber_expiration_interval: time::Duration, } impl PublisherDesc { async fn to_tokio_socket(&self) -> Result<UdpSocket> { let addr = match self.to_socket_addrs()?.next() { Some(addr) => addr, None => { return Err(Error::AddrParseError); } }; Ok(UdpSocket::bind(&addr).await?) } } #[derive(Debug)] pub enum PublisherConversionError { Time(proto::TimeError), NoExpiration, } impl std::fmt::Display for PublisherConversionError { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "Publisher Conversion Error: {:?}", self) } } impl std::error::Error for PublisherConversionError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } impl std::convert::From<proto::TimeError> for PublisherConversionError { fn from(error: proto::TimeError) -> Self { PublisherConversionError::Time(error) } } impl std::convert::TryFrom<proto::PublisherDesc> for PublisherDesc { type Error = PublisherConversionError; fn try_from(proto_value: proto::PublisherDesc) -> std::result::Result<Self, Self::Error> { let proto::PublisherDesc { name, host_name, port: port32, subscriber_expiration_interval: proto_interval, } = proto_value; let subscriber_expiration_interval: time::Duration = match proto_interval { Some(expiration) => expiration.into(), None => return Err(PublisherConversionError::NoExpiration), }; let port: u16 = port32 as u16; Ok(Self { name, host_name, port, subscriber_expiration_interval, }) } } impl<'a> ToSocketAddrs for PublisherDesc { type Iter = std::vec::IntoIter<SocketAddr>; fn to_socket_addrs(&self) -> io::Result<Self::Iter> { (self.host_name.as_str(), self.port).to_socket_addrs() } } impl fmt::Display for PublisherDesc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "name: {}, host_name: {}, port: {}", self.name, self.host_name, self.port ) } } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct ConnectionInfo { pub last_report: time::SystemTime, pub expiration: time::SystemTime, } #[cfg(test)] mod tests {}