use std::{any, fmt, marker::PhantomData, net::SocketAddr};
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct PeerAddr(pub SocketAddr);
impl PeerAddr {
pub fn into_inner(self) -> SocketAddr {
self.0
}
}
impl From<SocketAddr> for PeerAddr {
fn from(addr: SocketAddr) -> Self {
Self(addr)
}
}
impl fmt::Debug for PeerAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum HttpProtocol {
Http1,
Http2,
Unknown,
}
pub struct QueryItem<T> {
item: Option<Box<dyn any::Any>>,
_t: PhantomData<T>,
}
impl<T: any::Any> QueryItem<T> {
pub(crate) fn new(item: Option<Box<dyn any::Any>>) -> Self {
Self {
item,
_t: PhantomData,
}
}
pub fn get(&self) -> Option<T>
where
T: Copy,
{
self.item.as_ref().and_then(|v| v.downcast_ref().copied())
}
pub fn as_ref(&self) -> Option<&T> {
if let Some(ref item) = self.item {
item.downcast_ref()
} else {
None
}
}
}
impl<T: any::Any + fmt::Debug> fmt::Debug for QueryItem<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(v) = self.as_ref() {
f.debug_tuple("QueryItem").field(v).finish()
} else {
f.debug_tuple("QueryItem").field(&None::<T>).finish()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn peer_addr() {
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
let peer = PeerAddr::from(addr);
assert_eq!(peer, PeerAddr(addr));
assert_eq!(format!("{peer:?}"), "127.0.0.1:8080");
assert_eq!(peer.into_inner(), addr);
}
#[test]
fn query_item() {
let item = QueryItem::<u32>::new(Some(Box::new(10u32)));
assert_eq!(item.get(), Some(10));
assert_eq!(item.as_ref(), Some(&10));
assert_eq!(format!("{item:?}"), "QueryItem(10)");
let item = QueryItem::<u32>::new(Some(Box::new("str")));
assert_eq!(item.get(), None);
assert_eq!(item.as_ref(), None);
let item = QueryItem::<u32>::new(None);
assert_eq!(item.get(), None);
assert_eq!(item.as_ref(), None);
assert_eq!(format!("{item:?}"), "QueryItem(None)");
}
}