use std::fmt::Display;
use super::AsStr;
use crate::error::Error;
pub fn apply<T: Url>(v: &T, _: ()) -> Result<(), Error> {
if let Err(e) = v.validate_url() {
return Err(Error::new(format!("not a valid url: {e}")));
}
Ok(())
}
pub trait Url {
type Error: Display;
fn validate_url(&self) -> Result<(), Self::Error>;
}
impl<T: AsStr> Url for T {
type Error = url::ParseError;
fn validate_url(&self) -> Result<(), Self::Error> {
let _ = url::Url::parse(self.as_str())?;
Ok(())
}
}
impl<T: Url> Url for Option<T> {
type Error = T::Error;
fn validate_url(&self) -> Result<(), Self::Error> {
match self {
Some(value) => value.validate_url(),
None => Ok(()),
}
}
}