use std::{future::Future, time::Instant};
use agnostic_lite::RuntimeLite;
use bytes::Bytes;
use futures::AsyncRead;
pub use nodecraft::{resolver::AddressResolver, CheapClone, Transformable, *};
use crate::types::*;
use super::*;
mod stream;
pub use stream::*;
mod lpe;
pub use lpe::*;
#[cfg(any(test, feature = "test"))]
#[cfg_attr(docsrs, doc(cfg(feature = "test")))]
pub mod tests;
pub enum MaybeResolvedAddress<T: Transport> {
Resolved(<T::Resolver as AddressResolver>::ResolvedAddress),
Unresolved(<T::Resolver as AddressResolver>::Address),
}
impl<T: Transport> Clone for MaybeResolvedAddress<T> {
fn clone(&self) -> Self {
match self {
Self::Resolved(addr) => Self::Resolved(addr.clone()),
Self::Unresolved(addr) => Self::Unresolved(addr.clone()),
}
}
}
impl<T: Transport> CheapClone for MaybeResolvedAddress<T> {
fn cheap_clone(&self) -> Self {
match self {
Self::Resolved(addr) => Self::Resolved(addr.cheap_clone()),
Self::Unresolved(addr) => Self::Unresolved(addr.cheap_clone()),
}
}
}
impl<T: Transport> core::fmt::Debug for MaybeResolvedAddress<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Resolved(addr) => write!(f, "{addr:?}"),
Self::Unresolved(addr) => write!(f, "{addr:?}"),
}
}
}
impl<T: Transport> core::fmt::Display for MaybeResolvedAddress<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Resolved(addr) => write!(f, "{addr}"),
Self::Unresolved(addr) => write!(f, "{addr}"),
}
}
}
impl<T: Transport> PartialEq for MaybeResolvedAddress<T> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Resolved(addr1), Self::Resolved(addr2)) => addr1 == addr2,
(Self::Unresolved(addr1), Self::Unresolved(addr2)) => addr1 == addr2,
_ => false,
}
}
}
impl<T: Transport> Eq for MaybeResolvedAddress<T> {}
impl<T: Transport> core::hash::Hash for MaybeResolvedAddress<T> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
match self {
Self::Resolved(addr) => addr.hash(state),
Self::Unresolved(addr) => addr.hash(state),
}
}
}
impl<T: Transport> MaybeResolvedAddress<T> {
#[inline]
pub const fn resolved(addr: <T::Resolver as AddressResolver>::ResolvedAddress) -> Self {
Self::Resolved(addr)
}
#[inline]
pub const fn unresolved(addr: <T::Resolver as AddressResolver>::Address) -> Self {
Self::Unresolved(addr)
}
#[inline]
pub fn is_resolved(&self) -> bool {
matches!(self, Self::Resolved(_))
}
#[inline]
pub fn is_unresolved(&self) -> bool {
matches!(self, Self::Unresolved(_))
}
#[inline]
pub fn as_resolved(&self) -> Option<&<T::Resolver as AddressResolver>::ResolvedAddress> {
match self {
Self::Resolved(addr) => Some(addr),
Self::Unresolved(_) => None,
}
}
#[inline]
pub fn as_unresolved(&self) -> Option<&<T::Resolver as AddressResolver>::Address> {
match self {
Self::Resolved(_) => None,
Self::Unresolved(addr) => Some(addr),
}
}
#[inline]
pub fn as_resolved_mut(
&mut self,
) -> Option<&mut <T::Resolver as AddressResolver>::ResolvedAddress> {
match self {
Self::Resolved(addr) => Some(addr),
Self::Unresolved(_) => None,
}
}
#[inline]
pub fn as_unresolved_mut(&mut self) -> Option<&mut <T::Resolver as AddressResolver>::Address> {
match self {
Self::Resolved(_) => None,
Self::Unresolved(addr) => Some(addr),
}
}
#[inline]
pub fn into_resolved(self) -> Option<<T::Resolver as AddressResolver>::ResolvedAddress> {
match self {
Self::Resolved(addr) => Some(addr),
Self::Unresolved(_) => None,
}
}
#[inline]
pub fn into_unresolved(self) -> Option<<T::Resolver as AddressResolver>::Address> {
match self {
Self::Resolved(_) => None,
Self::Unresolved(addr) => Some(addr),
}
}
}
#[auto_impl::auto_impl(Box)]
pub trait TimeoutableReadStream: Unpin + Send + Sync + 'static {
fn set_read_deadline(&mut self, deadline: Option<Instant>);
fn read_deadline(&self) -> Option<Instant>;
}
#[auto_impl::auto_impl(Box)]
pub trait TimeoutableWriteStream: Unpin + Send + Sync + 'static {
fn set_write_deadline(&mut self, deadline: Option<Instant>);
fn write_deadline(&self) -> Option<Instant>;
}
pub trait TimeoutableStream:
TimeoutableReadStream + TimeoutableWriteStream + Unpin + Send + Sync + 'static
{
fn set_deadline(&mut self, deadline: Option<Instant>) {
Self::set_read_deadline(self, deadline);
Self::set_write_deadline(self, deadline);
}
fn deadline(&self) -> (Option<Instant>, Option<Instant>) {
(Self::read_deadline(self), Self::write_deadline(self))
}
}
impl<T: TimeoutableReadStream + TimeoutableWriteStream + Unpin + Send + Sync + 'static>
TimeoutableStream for T
{
}
pub trait TransportError: std::error::Error + Send + Sync + 'static {
fn is_remote_failure(&self) -> bool;
fn custom(err: std::borrow::Cow<'static, str>) -> Self;
}
#[auto_impl::auto_impl(Box, Arc)]
pub trait Wire: Send + Sync + 'static {
type Error: std::error::Error + Send + Sync + 'static;
type Id: Transformable;
type Address: Transformable;
fn encoded_len(msg: &Message<Self::Id, Self::Address>) -> usize;
fn encode_message(
msg: Message<Self::Id, Self::Address>,
dst: &mut [u8],
) -> Result<usize, Self::Error>;
fn encode_message_to_vec(msg: Message<Self::Id, Self::Address>) -> Result<Vec<u8>, Self::Error> {
let mut buf = vec![0; Self::encoded_len(&msg)];
Self::encode_message(msg, &mut buf)?;
Ok(buf)
}
fn encode_message_to_bytes(msg: Message<Self::Id, Self::Address>) -> Result<Bytes, Self::Error> {
Self::encode_message_to_vec(msg).map(Into::into)
}
fn decode_message(src: &[u8]) -> Result<(usize, Message<Self::Id, Self::Address>), Self::Error>;
fn decode_message_from_reader(
conn: impl AsyncRead + Send + Unpin,
) -> impl Future<Output = std::io::Result<(usize, Message<Self::Id, Self::Address>)>> + Send;
}
pub trait Transport: Sized + Send + Sync + 'static {
type Error: TransportError;
type Id: Id;
type Resolver: AddressResolver<Runtime = Self::Runtime>;
type Stream: TimeoutableStream + Send + Sync + 'static;
type Wire: Wire<Id = Self::Id, Address = <Self::Resolver as AddressResolver>::ResolvedAddress>;
type Runtime: RuntimeLite;
type Options: Send + Sync + 'static;
fn new(options: Self::Options) -> impl Future<Output = Result<Self, Self::Error>> + Send;
fn resolve(
&self,
addr: &<Self::Resolver as AddressResolver>::Address,
) -> impl Future<Output = Result<<Self::Resolver as AddressResolver>::ResolvedAddress, Self::Error>>
+ Send;
fn local_id(&self) -> &Self::Id;
fn local_address(&self) -> &<Self::Resolver as AddressResolver>::Address;
fn advertise_address(&self) -> &<Self::Resolver as AddressResolver>::ResolvedAddress;
#[cfg(feature = "encryption")]
#[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
fn keyring(&self) -> Option<&SecretKeyring>;
#[cfg(feature = "encryption")]
#[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
fn encryption_enabled(&self) -> bool;
fn max_payload_size(&self) -> usize;
fn packets_header_overhead(&self) -> usize;
fn packet_overhead(&self) -> usize;
fn blocked_address(
&self,
addr: &<Self::Resolver as AddressResolver>::ResolvedAddress,
) -> Result<(), Self::Error>;
fn read_message(
&self,
from: &<Self::Resolver as AddressResolver>::ResolvedAddress,
conn: &mut Self::Stream,
) -> impl Future<
Output = Result<
(
usize,
Message<Self::Id, <Self::Resolver as AddressResolver>::ResolvedAddress>,
),
Self::Error,
>,
> + Send;
fn send_message(
&self,
conn: &mut Self::Stream,
msg: Message<Self::Id, <Self::Resolver as AddressResolver>::ResolvedAddress>,
) -> impl Future<Output = Result<usize, Self::Error>> + Send;
fn send_packet(
&self,
addr: &<Self::Resolver as AddressResolver>::ResolvedAddress,
packet: Message<Self::Id, <Self::Resolver as AddressResolver>::ResolvedAddress>,
) -> impl Future<Output = Result<(usize, Instant), Self::Error>> + Send;
fn send_packets(
&self,
addr: &<Self::Resolver as AddressResolver>::ResolvedAddress,
packets: TinyVec<Message<Self::Id, <Self::Resolver as AddressResolver>::ResolvedAddress>>,
) -> impl Future<Output = Result<(usize, Instant), Self::Error>> + Send;
fn dial_with_deadline(
&self,
addr: &<Self::Resolver as AddressResolver>::ResolvedAddress,
deadline: Instant,
) -> impl Future<Output = Result<Self::Stream, Self::Error>> + Send;
fn cache_stream(
&self,
addr: &<Self::Resolver as AddressResolver>::ResolvedAddress,
stream: Self::Stream,
) -> impl Future<Output = Result<(), Self::Error>> + Send;
fn packet(
&self,
) -> PacketSubscriber<Self::Id, <Self::Resolver as AddressResolver>::ResolvedAddress>;
fn stream(
&self,
) -> StreamSubscriber<<Self::Resolver as AddressResolver>::ResolvedAddress, Self::Stream>;
fn shutdown(&self) -> impl Future<Output = Result<(), Self::Error>> + Send;
}