domain/new/rdata/dnssec/
ds.rs1use core::hash::{Hash, Hasher};
4use core::{cmp::Ordering, fmt};
5
6use domain_macros::*;
7
8use crate::new::base::CanonicalRecordData;
9use crate::new::base::build::{
10 BuildInMessage, NameCompressor, TruncationError,
11};
12use crate::new::base::wire::{AsBytes, U16};
13
14use super::SecAlg;
15
16#[derive(Debug, AsBytes, BuildBytes, ParseBytesZC, UnsizedCopy)]
20#[repr(C)]
21pub struct Ds {
22 pub keytag: U16,
24
25 pub algorithm: SecAlg,
27
28 pub digest_type: DigestType,
30
31 pub digest: [u8],
33}
34
35impl CanonicalRecordData for Ds {
38 fn cmp_canonical(&self, other: &Self) -> Ordering {
39 self.as_bytes().cmp(other.as_bytes())
40 }
41}
42
43impl BuildInMessage for Ds {
46 fn build_in_message(
47 &self,
48 contents: &mut [u8],
49 start: usize,
50 _compressor: &mut NameCompressor,
51 ) -> Result<usize, TruncationError> {
52 let bytes = self.as_bytes();
53 let end = start + bytes.len();
54 contents
55 .get_mut(start..end)
56 .ok_or(TruncationError)?
57 .copy_from_slice(bytes);
58 Ok(end)
59 }
60}
61
62impl PartialEq for Ds {
65 fn eq(&self, other: &Self) -> bool {
66 self.as_bytes() == other.as_bytes()
68 }
69}
70
71impl Eq for Ds {}
72
73impl Hash for Ds {
76 fn hash<H: Hasher>(&self, state: &mut H) {
77 state.write(self.as_bytes())
78 }
79}
80
81#[derive(
85 Copy,
86 Clone,
87 PartialEq,
88 Eq,
89 PartialOrd,
90 Ord,
91 Hash,
92 AsBytes,
93 BuildBytes,
94 ParseBytes,
95 ParseBytesZC,
96 SplitBytes,
97 SplitBytesZC,
98 UnsizedCopy,
99)]
100#[repr(transparent)]
101pub struct DigestType {
102 pub code: u8,
104}
105
106impl DigestType {
109 pub const SHA1: Self = Self { code: 1 };
111}
112
113impl fmt::Debug for DigestType {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.write_str(match *self {
118 Self::SHA1 => "DigestType::SHA1",
119 _ => return write!(f, "DigestType({})", self.code),
120 })
121 }
122}