use std::fmt::{Display, Formatter};
use crate::body::Empty;
use crate::Request;
use crate::request::Extract;
pub struct ClientIp(String);
impl From<String> for ClientIp {
fn from(value: String) -> Self {
ClientIp(value)
}
}
impl Clone for ClientIp {
fn clone(&self) -> Self {
ClientIp(self.0.clone())
}
}
impl Display for ClientIp {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<S> Extract<S> for ClientIp {
type Error = Empty;
fn extract(request: &Request, _: &S) -> impl Future<Output=Result<Self, Self::Error>> {
let ip_address = request
.extensions()
.get::<ClientIp>()
.map(|client| client.0.clone())
.unwrap_or_else(|| String::from("<Unknown IP>"));
async {
Ok(ClientIp(ip_address))
}
}
}