hickory_proto/rr/rdata/
openpgpkey.rs1use alloc::vec::Vec;
10use core::fmt;
11
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15use crate::{
16 error::ProtoResult,
17 rr::{RData, RecordData, RecordDataDecodable, RecordType},
18 serialize::{
19 binary::{BinDecoder, BinEncodable, BinEncoder, DecodeError, Restrict},
20 txt::ParseError,
21 },
22};
23
24#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
32#[derive(Debug, PartialEq, Eq, Hash, Clone)]
33#[non_exhaustive]
34pub struct OPENPGPKEY {
35 pub public_key: Vec<u8>,
39}
40
41impl OPENPGPKEY {
42 pub fn new(public_key: Vec<u8>) -> Self {
49 Self { public_key }
50 }
51
52 pub(crate) fn from_tokens<'i, I: Iterator<Item = &'i str>>(
65 mut tokens: I,
66 ) -> Result<Self, ParseError> {
67 let encoded_public_key = tokens.next().ok_or(ParseError::Message(
68 "OPENPGPKEY public key field is missing",
69 ))?;
70 let public_key = data_encoding::BASE64.decode(encoded_public_key.as_bytes())?;
71 Some(Self::new(public_key))
72 .filter(|_| tokens.next().is_none())
73 .ok_or(ParseError::Message("too many fields for OPENPGPKEY"))
74 }
75}
76
77impl BinEncodable for OPENPGPKEY {
78 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
79 encoder.emit_vec(&self.public_key)
80 }
81}
82
83impl<'r> RecordDataDecodable<'r> for OPENPGPKEY {
84 fn read_data(decoder: &mut BinDecoder<'r>, length: Restrict<u16>) -> Result<Self, DecodeError> {
85 let rdata_length = length.map(usize::from).unverified();
86 let public_key =
87 decoder.read_vec(rdata_length)?.unverified();
88 Ok(Self::new(public_key))
89 }
90}
91
92impl RecordData for OPENPGPKEY {
93 fn try_borrow(data: &RData) -> Option<&Self> {
94 match data {
95 RData::OPENPGPKEY(csync) => Some(csync),
96 _ => None,
97 }
98 }
99
100 fn record_type(&self) -> RecordType {
101 RecordType::OPENPGPKEY
102 }
103
104 fn into_rdata(self) -> RData {
105 RData::OPENPGPKEY(self)
106 }
107}
108
109impl fmt::Display for OPENPGPKEY {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
123 f.write_str(&data_encoding::BASE64.encode(&self.public_key))
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn test_parsing() {
133 assert!(OPENPGPKEY::from_tokens(core::iter::empty()).is_err());
134 assert!(OPENPGPKEY::from_tokens(vec!["äöüäööüä"].into_iter()).is_err());
135 assert!(OPENPGPKEY::from_tokens(vec!["ZmFpbGVk", "äöüäöüö"].into_iter()).is_err());
136
137 assert!(
138 OPENPGPKEY::from_tokens(vec!["dHJ1c3RfZG5zIGlzIGF3ZXNvbWU="].into_iter())
139 .map(|rd| rd == OPENPGPKEY::new(b"trust_dns is awesome".to_vec()))
140 .unwrap_or(false)
141 );
142 assert!(
143 OPENPGPKEY::from_tokens(vec!["c2VsZi1wcmFpc2Ugc3Rpbmtz"].into_iter())
144 .map(|rd| rd == OPENPGPKEY::new(b"self-praise stinks".to_vec()))
145 .unwrap_or(false)
146 );
147 }
148}