use core::marker::PhantomData;
use byteorder::{ByteOrder, NetworkEndian};
use crate::core::{Class, Type};
use crate::emit::message::{MessageBuilder, QuestionStep};
use crate::emit::name::{NameBuilder, NameError};
use crate::emit::{Buffer, Builder, ChildBuilder, GrowError, PushBuilder, Sink};
error!(QuestionError, Grow, Name);
#[derive(Debug, displaydoc::Display)]
#[prefix_enum_doc_attributes]
pub enum QuestionError {
Grow(GrowError),
Name(NameError),
}
#[must_use]
pub struct QuestionBuilder<'b, P> {
buffer: PhantomData<&'b mut dyn Buffer>,
parent: P,
}
impl<'b, P: Builder<'b>> ChildBuilder<'b, P> for QuestionBuilder<'b, P> {
fn parent(&mut self) -> &mut P {
&mut self.parent
}
}
impl<'b, P: Builder<'b>> PushBuilder<'b, P> for QuestionBuilder<'b, P> {
type Error = QuestionError;
fn push(parent: P) -> Result<Self, QuestionError> {
Ok(Self {
buffer: PhantomData,
parent,
})
}
}
builder! {
<'b, P> QuestionBuilder {
Builder;
}
}
impl<__> QuestionBuilder<'_, __> {}
builder! {
<'b, P> QuestionBuilder {
@ <P>:
pub fn qname(mut self) = [push NameBuilder | QuestionError::Name] { self }
}
}
builder! {
<'b, P> QuestionBuilder {
@ <MessageBuilder<'b, P, Q>> [Q: QuestionStep]:
pub(in crate::emit) fn finish(
mut self,
qtype: Type,
qclass: Class,
) -> Result<MessageBuilder<'b, P, Q>, QuestionError> = {
NetworkEndian::write_u16(
self.sink().grow_mut(2).map_err(QuestionError::Grow)?,
qtype.value(),
);
NetworkEndian::write_u16(
self.sink().grow_mut(2).map_err(QuestionError::Grow)?,
qclass.value(),
);
Ok(self.parent)
}
}
}