use core::hash::{Hash, Hasher};
use core::{cmp::Ordering, fmt};
use domain_macros::*;
use crate::new::base::build::{
BuildInMessage, NameCompressor, TruncationError,
};
use crate::new::base::wire::{AsBytes, U16};
use crate::new::base::CanonicalRecordData;
use super::SecAlg;
#[derive(Debug, AsBytes, BuildBytes, ParseBytesZC, UnsizedCopy)]
#[repr(C)]
pub struct Ds {
pub keytag: U16,
pub algorithm: SecAlg,
pub digest_type: DigestType,
pub digest: [u8],
}
impl CanonicalRecordData for Ds {
fn cmp_canonical(&self, other: &Self) -> Ordering {
self.as_bytes().cmp(other.as_bytes())
}
}
impl BuildInMessage for Ds {
fn build_in_message(
&self,
contents: &mut [u8],
start: usize,
_compressor: &mut NameCompressor,
) -> Result<usize, TruncationError> {
let bytes = self.as_bytes();
let end = start + bytes.len();
contents
.get_mut(start..end)
.ok_or(TruncationError)?
.copy_from_slice(bytes);
Ok(end)
}
}
impl PartialEq for Ds {
fn eq(&self, other: &Self) -> bool {
self.as_bytes() == other.as_bytes()
}
}
impl Eq for Ds {}
impl Hash for Ds {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write(self.as_bytes())
}
}
#[derive(
Copy,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
AsBytes,
BuildBytes,
ParseBytes,
ParseBytesZC,
SplitBytes,
SplitBytesZC,
UnsizedCopy,
)]
#[repr(transparent)]
pub struct DigestType {
pub code: u8,
}
impl DigestType {
pub const SHA1: Self = Self { code: 1 };
}
impl fmt::Debug for DigestType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
Self::SHA1 => "DigestType::SHA1",
_ => return write!(f, "DigestType({})", self.code),
})
}
}