use std::boxed::Box;
use std::fmt::Debug;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use crate::base::iana::Class;
use crate::zonefile::inplace;
use super::error::{RecordError, ZoneErrors};
use super::in_memory::ZoneBuilder;
use super::traits::WritableZone;
use super::types::StoredName;
use super::{parsed, ReadableZone, ZoneStore};
#[derive(Clone, Debug)]
pub struct Zone {
store: Arc<dyn ZoneStore>,
}
impl Zone {
pub fn new(data: impl ZoneStore + 'static) -> Self {
Zone {
store: Arc::new(data),
}
}
pub fn into_inner(self) -> Arc<dyn ZoneStore> {
self.store
}
pub fn class(&self) -> Class {
self.store.class()
}
pub fn apex_name(&self) -> &StoredName {
self.store.apex_name()
}
pub fn read(&self) -> Box<dyn ReadableZone> {
self.store.clone().read()
}
pub fn write(
&self,
) -> Pin<Box<dyn Future<Output = Box<dyn WritableZone>> + Send + Sync>>
{
self.store.clone().write()
}
}
impl AsRef<dyn ZoneStore> for Zone {
fn as_ref(&self) -> &dyn ZoneStore {
self.store.as_ref()
}
}
impl TryFrom<inplace::Zonefile> for Zone {
type Error = ZoneErrors<RecordError>;
fn try_from(source: inplace::Zonefile) -> Result<Self, Self::Error> {
parsed::Zonefile::try_from(source)?.try_into()
}
}
impl From<ZoneBuilder> for Zone {
fn from(builder: ZoneBuilder) -> Self {
builder.build()
}
}
impl TryFrom<parsed::Zonefile> for Zone {
type Error = ZoneErrors<RecordError>;
fn try_from(source: parsed::Zonefile) -> Result<Self, Self::Error> {
Ok(Zone::from(ZoneBuilder::try_from(source).map_err(
|errors| {
let mut new_errors = Self::Error::default();
for (name, err) in errors {
new_errors
.add_error(name, RecordError::InvalidRecord(err))
}
new_errors
},
)?))
}
}