nomilo/src/models/name.rs

95 lines
2.0 KiB
Rust

use std::ops::Deref;
use rocket::request::FromParam;
use rocket::form::{self, FromFormField, ValueField};
use serde::{Deserialize, Serialize, Deserializer, Serializer};
use trust_dns_proto::error::ProtoError;
use crate::dns::Name;
#[derive(Debug, Clone)]
pub struct SerdeName(pub(crate)Name);
impl Deref for SerdeName {
type Target = Name;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'de> Deserialize<'de> for SerdeName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
use serde::de::Error;
String::deserialize(deserializer)
.and_then(|string|
Name::from_utf8(&string)
.map_err(|e| Error::custom(e.to_string()))
).map( SerdeName)
}
}
impl Serialize for SerdeName {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer
{
self.0.to_utf8().serialize(serializer)
}
}
impl SerdeName {
pub fn into_inner(self) -> Name {
self.0
}
}
fn parse_absolute_name(name: &str) -> Result<AbsoluteName, ProtoError> {
let mut name = Name::from_utf8(name)?;
if !name.is_fqdn() {
name.set_fqdn(true);
}
Ok(AbsoluteName(SerdeName(name)))
}
#[derive(Debug, Deserialize)]
pub struct AbsoluteName(SerdeName);
impl<'r> FromParam<'r> for AbsoluteName {
type Error = ProtoError;
fn from_param(param: &'r str) -> Result<Self, Self::Error> {
let name = parse_absolute_name(param)?;
Ok(name)
}
}
#[async_trait]
impl<'v> FromFormField<'v> for AbsoluteName {
fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> {
let name = parse_absolute_name(field.value)
.map_err(|_| form::Error::validation("Invalid name"))?;
Ok(name)
}
}
impl Deref for AbsoluteName {
type Target = Name;
fn deref(&self) -> &Self::Target {
&self.0.0
}
}
impl AbsoluteName {
pub fn into_inner(self) -> Name {
self.0.0
}
}