use core::any::Any;
use core::future::ready;
use core::ops::Deref;
use core::pin::Pin;
use std::boxed::Box;
use std::fmt::Debug;
use std::future::Future;
use std::io;
use std::sync::Arc;
use bytes::Bytes;
use futures_util::Stream;
use crate::base::iana::Class;
use crate::base::name::Label;
use crate::base::{Name, Rtype, Serial, ToName};
use super::answer::Answer;
use super::error::OutOfZone;
use super::types::{InMemoryZoneDiff, ZoneCut};
use super::{SharedRr, SharedRrset, StoredName, WalkOp};
pub trait ZoneStore: Debug + Sync + Send + Any {
fn class(&self) -> Class;
fn apex_name(&self) -> &StoredName;
fn read(self: Arc<Self>) -> Box<dyn ReadableZone>;
fn write(
self: Arc<Self>,
) -> Pin<
Box<
dyn Future<Output = Box<dyn WritableZone + 'static>>
+ Send
+ Sync
+ 'static,
>,
>;
fn as_any(&self) -> &dyn Any;
}
pub trait ReadableZone: Send + Sync {
fn is_async(&self) -> bool {
true
}
fn query(
&self,
_qname: Name<Bytes>,
_qtype: Rtype,
) -> Result<Answer, OutOfZone>;
fn walk(&self, _op: WalkOp);
fn query_async(
&self,
qname: Name<Bytes>,
qtype: Rtype,
) -> Pin<Box<dyn Future<Output = Result<Answer, OutOfZone>> + Send + Sync>>
{
Box::pin(ready(self.query(qname, qtype)))
}
fn walk_async(
&self,
op: WalkOp,
) -> Pin<Box<dyn Future<Output = ()> + Send + Sync>> {
self.walk(op);
Box::pin(ready(()))
}
}
pub trait WritableZone: Send + Sync {
#[allow(clippy::type_complexity)]
fn open(
&self,
create_diff: bool,
) -> Pin<
Box<
dyn Future<Output = Result<Box<dyn WritableZoneNode>, io::Error>>
+ Send
+ Sync,
>,
>;
fn commit(
&mut self,
bump_soa_serial: bool,
) -> Pin<
Box<
dyn Future<Output = Result<Option<InMemoryZoneDiff>, io::Error>>
+ Send
+ Sync,
>,
>;
}
pub trait WritableZoneNode: Send + Sync {
#[allow(clippy::type_complexity)]
fn update_child(
&self,
label: &Label,
) -> Pin<
Box<
dyn Future<Output = Result<Box<dyn WritableZoneNode>, io::Error>>
+ Send
+ Sync,
>,
>;
fn get_rrset(
&self,
rtype: Rtype,
) -> Pin<
Box<
dyn Future<Output = Result<Option<SharedRrset>, io::Error>>
+ Send
+ Sync,
>,
>;
fn update_rrset(
&self,
rrset: SharedRrset,
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + Sync>>;
fn remove_rrset(
&self,
rtype: Rtype,
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + Sync>>;
fn make_regular(
&self,
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + Sync>>;
fn make_zone_cut(
&self,
cut: ZoneCut,
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + Sync>>;
fn make_cname(
&self,
cname: SharedRr,
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + Sync>>;
fn remove_all(
&self,
) -> Pin<Box<dyn Future<Output = Result<(), io::Error>> + Send + Sync>>;
}
pub trait ZoneDiffItem {
fn key(&self) -> &(StoredName, Rtype);
fn value(&self) -> &SharedRrset;
}
pub trait ZoneDiff {
type Item<'a>: ZoneDiffItem + Send
where
Self: 'a;
type Stream<'a>: Stream<Item = Self::Item<'a>> + Send
where
Self: 'a;
fn start_serial(
&self,
) -> Pin<Box<dyn Future<Output = Serial> + Send + '_>>;
fn end_serial(&self)
-> Pin<Box<dyn Future<Output = Serial> + Send + '_>>;
fn added(&self) -> Self::Stream<'_>;
fn removed(&self) -> Self::Stream<'_>;
fn get_added(
&self,
name: impl ToName,
rtype: Rtype,
) -> Pin<Box<dyn Future<Output = Option<&SharedRrset>> + Send + '_>>;
fn get_removed(
&self,
name: impl ToName,
rtype: Rtype,
) -> Pin<Box<dyn Future<Output = Option<&SharedRrset>> + Send + '_>>;
}
impl<T: ZoneDiff> ZoneDiff for Arc<T> {
type Item<'a>
= T::Item<'a>
where
Self: 'a;
type Stream<'a>
= T::Stream<'a>
where
Self: 'a;
fn start_serial(
&self,
) -> Pin<Box<dyn Future<Output = Serial> + Send + '_>> {
Arc::deref(self).start_serial()
}
fn end_serial(
&self,
) -> Pin<Box<dyn Future<Output = Serial> + Send + '_>> {
Arc::deref(self).end_serial()
}
fn added(&self) -> Self::Stream<'_> {
Arc::deref(self).added()
}
fn removed(&self) -> Self::Stream<'_> {
Arc::deref(self).removed()
}
fn get_added(
&self,
name: impl ToName,
rtype: Rtype,
) -> Pin<Box<dyn Future<Output = Option<&SharedRrset>> + Send + '_>> {
Arc::deref(self).get_added(name, rtype)
}
fn get_removed(
&self,
name: impl ToName,
rtype: Rtype,
) -> Pin<Box<dyn Future<Output = Option<&SharedRrset>> + Send + '_>> {
Arc::deref(self).get_removed(name, rtype)
}
}