diff --git a/src/base/charstr.rs b/src/base/charstr.rs index e0426929..889e7c24 100644 --- a/src/base/charstr.rs +++ b/src/base/charstr.rs @@ -344,7 +344,7 @@ impl Parse for CharStr { } impl + ?Sized> Compose for CharStr { - fn compose( + fn compose>( &self, target: &mut Target, ) -> Result<(), ShortBuf> { @@ -578,7 +578,7 @@ impl CharStrBuilder { /// If the octet sequence is longer than 255 octets, an error is /// returned. pub fn from_builder(builder: Builder) -> Result { - if builder.as_ref().len() > 255 { + if builder.len() > 255 { Err(CharStrError) } else { Ok(unsafe { Self::from_builder_unchecked(builder) }) @@ -614,7 +614,10 @@ impl CharStrBuilder { impl CharStrBuilder { /// Returns an octet slice of the string assembled so far. - pub fn as_slice(&self) -> &[u8] { + pub fn as_slice(&self) -> &[u8] + where + Builder: AsRef<[u8]>, + { self.0.as_ref() } @@ -651,6 +654,14 @@ impl OctetsBuilder for CharStrBuilder { fn freeze(self) -> Self::Octets { self.0.freeze() } + + fn len(&self) -> usize { + self.0.len() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } } //--- Deref and DerefMut @@ -674,7 +685,7 @@ where //--- AsRef and AsMut -impl AsRef<[u8]> for CharStrBuilder { +impl> AsRef<[u8]> for CharStrBuilder { fn as_ref(&self) -> &[u8] { self.0.as_ref() } diff --git a/src/base/iana/macros.rs b/src/base/iana/macros.rs index 8d690c19..fc445dd0 100644 --- a/src/base/iana/macros.rs +++ b/src/base/iana/macros.rs @@ -105,7 +105,7 @@ macro_rules! int_enum { } impl $crate::base::octets::Compose for $ianatype { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), $crate::base::octets::ShortBuf> { diff --git a/src/base/message.rs b/src/base/message.rs index 796994c1..297a901f 100644 --- a/src/base/message.rs +++ b/src/base/message.rs @@ -561,7 +561,7 @@ where R: AsRecord + 's, F: FnMut(ParsedRecord<&'s Octets>) -> Option, T: Into>, - O: OctetsBuilder, + O: OctetsBuilder + AsMut<[u8]>, { let mut source = self.answer()?; let mut target = target.into(); diff --git a/src/base/message_builder.rs b/src/base/message_builder.rs index 6dc2dbca..730c0de5 100644 --- a/src/base/message_builder.rs +++ b/src/base/message_builder.rs @@ -219,7 +219,7 @@ impl MessageBuilder> { } } -impl MessageBuilder { +impl> MessageBuilder { /// Starts creating an answer for the given message. /// /// Specifically, this sets the ID, QR, OPCODE, RD, and RCODE fields @@ -270,21 +270,23 @@ impl MessageBuilder { /// # Access to the Message Header /// -impl MessageBuilder { +impl> MessageBuilder { /// Return the current value of the message header. pub fn header(&self) -> Header { *Header::for_message_slice(self.target.as_ref()) } - /// Returns a mutable reference to the message header for manipulations. - pub fn header_mut(&mut self) -> &mut Header { - Header::for_message_slice_mut(self.target.as_mut()) - } - /// Return the current value of the message header counts. pub fn counts(&self) -> HeaderCounts { *HeaderCounts::for_message_slice(self.target.as_ref()) } +} + +impl> MessageBuilder { + /// Returns a mutable reference to the message header for manipulations. + pub fn header_mut(&mut self) -> &mut Header { + Header::for_message_slice_mut(self.target.as_mut()) + } /// Returns a mutable reference to the message header counts. fn counts_mut(&mut self) -> &mut HeaderCounts { @@ -382,7 +384,7 @@ impl MessageBuilder { impl From> for MessageBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: QuestionBuilder) -> Self { src.builder() @@ -391,7 +393,7 @@ where impl From> for MessageBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AnswerBuilder) -> Self { src.builder() @@ -400,7 +402,7 @@ where impl From> for MessageBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AuthorityBuilder) -> Self { src.builder() @@ -409,7 +411,7 @@ where impl From> for MessageBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AdditionalBuilder) -> Self { src.builder() @@ -465,7 +467,9 @@ impl QuestionBuilder { fn new(builder: MessageBuilder) -> Self { Self { builder } } +} +impl> QuestionBuilder { /// Appends a question to the question section. /// /// This method accepts anything that implements the [`AsQuestion`] @@ -504,7 +508,7 @@ impl QuestionBuilder { /// # Conversions /// /// Additional conversion are available via the `Deref` implementation. -impl QuestionBuilder { +impl> QuestionBuilder { /// Rewinds to an empty question section. /// /// All previously added questions will be lost. @@ -521,7 +525,9 @@ impl QuestionBuilder { self.rewind(); self.builder } +} +impl QuestionBuilder { /// Converts the question builder into a question builder. /// /// In other words, doesn’t do anything. @@ -589,7 +595,7 @@ where impl From> for QuestionBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AnswerBuilder) -> Self { src.question() @@ -598,7 +604,7 @@ where impl From> for QuestionBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AuthorityBuilder) -> Self { src.question() @@ -607,7 +613,7 @@ where impl From> for QuestionBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AdditionalBuilder) -> Self { src.question() @@ -692,11 +698,13 @@ impl AnswerBuilder { /// Assumes that all three record sections are empty. fn new(builder: MessageBuilder) -> Self { AnswerBuilder { - start: builder.target.as_ref().len(), + start: builder.target.len(), builder, } } +} +impl> AnswerBuilder { /// Appends a record to the answer section. /// /// This methods accepts anything that implements the [`AsRecord`] trait. @@ -738,7 +746,7 @@ impl AnswerBuilder { /// # Conversions /// /// Additional conversion are available via the `Deref` implementation. -impl AnswerBuilder { +impl> AnswerBuilder { /// Rewinds to an empty answer section. /// /// All previously added answers will be lost. @@ -763,7 +771,9 @@ impl AnswerBuilder { self.rewind(); QuestionBuilder::new(self.builder) } +} +impl AnswerBuilder { /// Converts the answer builder into an answer builder. /// /// This doesn’t do anything, really. @@ -833,7 +843,7 @@ where impl From> for AnswerBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AuthorityBuilder) -> Self { src.answer() @@ -842,7 +852,7 @@ where impl From> for AnswerBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AdditionalBuilder) -> Self { src.answer() @@ -927,11 +937,13 @@ impl AuthorityBuilder { /// Assumes that the authority and additional sections are empty. fn new(answer: AnswerBuilder) -> Self { AuthorityBuilder { - start: answer.as_target().as_ref().len(), + start: answer.as_target().len(), answer, } } +} +impl> AuthorityBuilder { /// Appends a record to the authority section. /// /// This methods accepts anything that implements the [`AsRecord`] trait. @@ -973,7 +985,7 @@ impl AuthorityBuilder { /// /// Additional conversion methods are available via the `Deref` /// implementation. -impl AuthorityBuilder { +impl> AuthorityBuilder { /// Rewinds to an empty authority section. /// /// All previously added authority records will be lost. @@ -1006,7 +1018,9 @@ impl AuthorityBuilder { self.rewind(); self.answer } +} +impl AuthorityBuilder { /// Converts the authority builder into an authority builder. /// /// This is identical to the identity function. @@ -1078,7 +1092,7 @@ where impl From> for AuthorityBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn from(src: AdditionalBuilder) -> Self { src.authority() @@ -1168,11 +1182,13 @@ impl AdditionalBuilder { /// Assumes that the additional section is currently empty. fn new(authority: AuthorityBuilder) -> Self { AdditionalBuilder { - start: authority.as_target().as_ref().len(), + start: authority.as_target().len(), authority, } } +} +impl> AdditionalBuilder { /// Appends a record to the additional section. /// /// This methods accepts anything that implements the [`AsRecord`] trait. @@ -1208,7 +1224,12 @@ impl AdditionalBuilder { err }) } +} +impl AdditionalBuilder +where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, +{ /// Appends and builds an OPT record. /// /// The actual building of the record is handled by a closure that @@ -1231,7 +1252,7 @@ impl AdditionalBuilder { /// /// Additional conversion methods are available via the `Deref` /// implementation. -impl AdditionalBuilder { +impl> AdditionalBuilder { /// Rewinds to an empty additional section. /// /// All previously added additional records will be lost. @@ -1272,7 +1293,9 @@ impl AdditionalBuilder { self.rewind(); self.authority } +} +impl AdditionalBuilder { /// Converts the additional builder into an additional builder. /// /// In other words, does absolutely nothing. @@ -1406,14 +1429,14 @@ pub trait RecordSectionBuilder { impl RecordSectionBuilder for AnswerBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn push(&mut self, record: impl AsRecord) -> Result<(), ShortBuf> { Self::push(self, record) } } -impl RecordSectionBuilder +impl> RecordSectionBuilder for AuthorityBuilder { fn push(&mut self, record: impl AsRecord) -> Result<(), ShortBuf> { @@ -1423,7 +1446,7 @@ impl RecordSectionBuilder impl RecordSectionBuilder for AdditionalBuilder where - Target: OctetsBuilder, + Target: OctetsBuilder + AsMut<[u8]>, { fn push(&mut self, record: impl AsRecord) -> Result<(), ShortBuf> { Self::push(self, record) @@ -1452,12 +1475,15 @@ pub struct OptBuilder<'a, Target> { arcount: u16, } -impl<'a, Target: OctetsBuilder> OptBuilder<'a, Target> { +impl<'a, Target> OptBuilder<'a, Target> +where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, +{ /// Creates a new opt builder atop an additional builder. fn new( additional: &'a mut AdditionalBuilder, ) -> Result { - let start = additional.as_target().as_ref().len(); + let start = additional.as_target().len(); let arcount = additional.counts().arcount(); let err = additional @@ -1624,7 +1650,7 @@ pub struct StreamTarget { target: Target, } -impl StreamTarget { +impl> StreamTarget { /// Creates a new stream target wrapping an octets builder. /// /// The function will truncate the builder back to empty and appends the @@ -1660,11 +1686,16 @@ impl StreamTarget { } /// Updates the length value to the current length of the target. - fn update_shim(&mut self) { + fn update_shim(&mut self) + where + Target: AsMut<[u8]>, + { let len = (self.target.len() - 2) as u16; self.target.as_mut()[..2].copy_from_slice(&len.to_be_bytes()) } +} +impl> StreamTarget { /// Returns an octets slice of the message for stream transports. /// /// The slice will start with the length octets and can be send as is @@ -1699,7 +1730,10 @@ impl> AsMut<[u8]> for StreamTarget { //--- OctetsBuilder -impl OctetsBuilder for StreamTarget { +impl OctetsBuilder for StreamTarget +where + Target: OctetsBuilder + AsMut<[u8]>, +{ type Octets = Target::Octets; fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> { @@ -1720,6 +1754,14 @@ impl OctetsBuilder for StreamTarget { fn freeze(self) -> Self::Octets { self.target.freeze() } + + fn len(&self) -> usize { + self.target.len() - 2 + } + + fn is_empty(&self) -> bool { + self.target.len() > 2 + } } //------------ StaticCompressor ---------------------------------------------- @@ -1835,7 +1877,10 @@ impl> AsMut<[u8]> for StaticCompressor { //--- OctetsBuilder -impl OctetsBuilder for StaticCompressor { +impl OctetsBuilder for StaticCompressor +where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, +{ type Octets = Target::Octets; fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> { @@ -1895,6 +1940,14 @@ impl OctetsBuilder for StaticCompressor { fn freeze(self) -> Self::Octets { self.target.freeze() } + + fn len(&self) -> usize { + self.target.len() + } + + fn is_empty(&self) -> bool { + self.target.is_empty() + } } //------------ TreeCompressor ------------------------------------------------ @@ -2044,7 +2097,10 @@ impl> AsMut<[u8]> for TreeCompressor { } #[cfg(feature = "std")] -impl OctetsBuilder for TreeCompressor { +impl OctetsBuilder for TreeCompressor +where + Target: OctetsBuilder + AsMut<[u8]>, +{ type Octets = Target::Octets; fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> { @@ -2100,6 +2156,14 @@ impl OctetsBuilder for TreeCompressor { fn freeze(self) -> Self::Octets { self.target.freeze() } + + fn len(&self) -> usize { + self.target.len() + } + + fn is_empty(&self) -> bool { + self.target.is_empty() + } } //============ Testing ======================================================= @@ -2152,6 +2216,8 @@ mod test { // Convert the builder into the actual message. let target = msg.finish().into_target(); + eprintln!("target {}", target.len()); + // Reparse message and check contents let msg = Message::from_octets(target.as_dgram_slice()).unwrap(); let q = msg.first_question().unwrap(); @@ -2204,7 +2270,10 @@ mod test { assert_eq!(opts.next(), Some(Ok(nsid))); } - fn create_compressed>(target: T) -> T { + fn create_compressed(target: T) -> T + where + T: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + { let mut msg = MessageBuilder::from_target(target).unwrap().question(); msg.header_mut().set_rcode(Rcode::NXDomain); msg.header_mut().set_rd(true); diff --git a/src/base/name/builder.rs b/src/base/name/builder.rs index 9cd60f99..5745a12f 100644 --- a/src/base/name/builder.rs +++ b/src/base/name/builder.rs @@ -70,7 +70,7 @@ impl DnameBuilder { /// consititutes a correctly encoded relative domain name. pub fn from_builder(builder: Builder) -> Result where - Builder: OctetsBuilder, + Builder: OctetsBuilder + AsRef<[u8]>, { RelativeDname::check_slice(builder.as_ref())?; Ok(unsafe { DnameBuilder::from_builder_unchecked(builder) }) @@ -110,6 +110,18 @@ impl DnameBuilder { } impl DnameBuilder { + /// Returns the length of the already assembled domain name. + pub fn len(&self) -> usize { + self.builder.len() + } + + /// Returns whether the name is still empty. + pub fn is_empty(&self) -> bool { + self.builder.is_empty() + } +} + +impl> DnameBuilder { /// Returns whether there currently is a label under construction. /// /// This returns `false` if the name is still empty or if the last thing @@ -322,7 +334,7 @@ impl Default for DnameBuilder { //--- Deref and AsRef -impl ops::Deref for DnameBuilder { +impl> ops::Deref for DnameBuilder { type Target = [u8]; fn deref(&self) -> &[u8] { @@ -330,7 +342,7 @@ impl ops::Deref for DnameBuilder { } } -impl AsRef<[u8]> for DnameBuilder { +impl> AsRef<[u8]> for DnameBuilder { fn as_ref(&self) -> &[u8] { self.builder.as_ref() } diff --git a/src/base/name/chain.rs b/src/base/name/chain.rs index a8088438..b82d22bc 100644 --- a/src/base/name/chain.rs +++ b/src/base/name/chain.rs @@ -100,7 +100,7 @@ impl Chain { //--- Compose impl Compose for Chain { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -110,7 +110,7 @@ impl Compose for Chain { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -126,7 +126,7 @@ where Octets: AsRef<[u8]>, R: ToDname, { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -141,7 +141,7 @@ where } } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/name/dname.rs b/src/base/name/dname.rs index 12f9eafa..331b0d21 100644 --- a/src/base/name/dname.rs +++ b/src/base/name/dname.rs @@ -95,7 +95,7 @@ impl Dname { pub fn from_chars(chars: C) -> Result where Octets: FromBuilder, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, C: IntoIterator, { let mut builder = DnameBuilder::::new(); @@ -629,7 +629,7 @@ where impl FromStr for Dname where Octets: FromBuilder, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { type Err = FromStrError; @@ -785,14 +785,14 @@ fn name_len>( } impl + ?Sized> Compose for Dname { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { target.append_slice(self.0.as_ref()) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -879,7 +879,7 @@ where impl<'de, Octets> serde::Deserialize<'de> for Dname where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { fn deserialize>( deserializer: D, @@ -892,7 +892,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = Dname; @@ -933,7 +933,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = Dname; diff --git a/src/base/name/label.rs b/src/base/name/label.rs index 7b69b236..235094c5 100644 --- a/src/base/name/label.rs +++ b/src/base/name/label.rs @@ -247,7 +247,7 @@ impl Label { //--- Compose impl Compose for Label { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -257,7 +257,7 @@ impl Compose for Label { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/name/parsed.rs b/src/base/name/parsed.rs index ddfcc348..d5736757 100644 --- a/src/base/name/parsed.rs +++ b/src/base/name/parsed.rs @@ -399,7 +399,7 @@ where } impl> Compose for ParsedDname { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -415,7 +415,7 @@ impl> Compose for ParsedDname { } } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/name/relative.rs b/src/base/name/relative.rs index 57f2cab5..34e83877 100644 --- a/src/base/name/relative.rs +++ b/src/base/name/relative.rs @@ -3,7 +3,9 @@ use super::super::octets::{ ParseError, ShortBuf, }; #[cfg(feature = "serde")] -use super::super::octets::{DeserializeOctets, FromBuilder, SerializeOctets}; +use super::super::octets::{ + DeserializeOctets, EmptyBuilder, FromBuilder, SerializeOctets, +}; use super::builder::{DnameBuilder, PushError}; use super::chain::{Chain, LongChainError}; use super::dname::Dname; @@ -240,6 +242,7 @@ impl RelativeDname { > where Octets: IntoBuilder, + ::Builder: AsMut<[u8]>, { self.into_builder().into_dname() } @@ -657,14 +660,14 @@ impl + ?Sized> ToRelativeDname for RelativeDname { //--- Compose impl + ?Sized> Compose for RelativeDname { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { target.append_slice(self.0.as_ref()) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -785,7 +788,7 @@ where impl<'de, Octets> serde::Deserialize<'de> for RelativeDname where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: crate::base::octets::EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { fn deserialize>( deserializer: D, @@ -798,8 +801,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder - + crate::base::octets::EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = RelativeDname; @@ -842,8 +844,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder - + crate::base::octets::EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = RelativeDname; diff --git a/src/base/name/uncertain.rs b/src/base/name/uncertain.rs index 8d19e57c..6df35875 100644 --- a/src/base/name/uncertain.rs +++ b/src/base/name/uncertain.rs @@ -124,7 +124,7 @@ impl UncertainDname { pub fn from_chars(chars: C) -> Result where Octets: FromBuilder, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, C: IntoIterator, { let mut builder = @@ -221,7 +221,8 @@ impl UncertainDname { > where Octets: AsRef<[u8]> + IntoBuilder, - ::Builder: OctetsBuilder, + ::Builder: + OctetsBuilder + AsMut<[u8]>, { match self { UncertainDname::Absolute(name) => Ok(name), @@ -306,7 +307,7 @@ impl From> for UncertainDname { impl str::FromStr for UncertainDname where Octets: FromBuilder, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { type Err = FromStrError; @@ -384,7 +385,7 @@ impl<'a, Octets: AsRef<[u8]>> IntoIterator for &'a UncertainDname { //--- Compose impl> Compose for UncertainDname { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -394,7 +395,7 @@ impl> Compose for UncertainDname { } } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -515,7 +516,7 @@ where impl<'de, Octets> serde::Deserialize<'de> for UncertainDname where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { fn deserialize>( deserializer: D, @@ -528,7 +529,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = UncertainDname; @@ -571,7 +572,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = UncertainDname; diff --git a/src/base/octets.rs b/src/base/octets.rs index 3d45f8e1..6561f0f9 100644 --- a/src/base/octets.rs +++ b/src/base/octets.rs @@ -175,6 +175,8 @@ use smallvec::{Array, SmallVec}; #[cfg(feature = "std")] use std::borrow::Cow; #[cfg(feature = "std")] +use std::mem; +#[cfg(feature = "std")] use std::vec::Vec; //============ Octets and Octet Builders ===================================== @@ -459,17 +461,19 @@ impl> OctetsInto for Source { /// octets sequence by appending the contents of octet slices. The buffers /// may consist of a predefined amount of space or grow as needed. /// -/// Octet builders provide access to the already assembled data through -/// octet slices via their implementations of `AsRef<[u8]>` and -/// `AsMut<[u8]>`. -pub trait OctetsBuilder: AsRef<[u8]> + AsMut<[u8]> + Sized { +/// The trait does not require octet builder to provide access to the already +/// assembled data. However, implementations are likely to do so, anyway, via +/// implementations of `AsRef<[u8]>` and `AsMut<[u8]>`. If access becomes +/// necessary when using an octets builder, simply add these as extra trait +/// bounds. +pub trait OctetsBuilder: Sized { /// The type of the octets the builder can be converted into. /// /// If `Octets` implements [`IntoBuilder`], the `Builder` associated /// type of that trait must be `Self`. /// /// [`IntoBuilder`]: trait.IntoBuilder.html - type Octets: AsRef<[u8]>; + type Octets; /// Appends the content of a slice to the builder. /// @@ -484,19 +488,10 @@ pub trait OctetsBuilder: AsRef<[u8]> + AsMut<[u8]> + Sized { fn freeze(self) -> Self::Octets; /// Returns the length of the already assembled data. - /// - /// This is a convenience method and identical to `self.as_ref().len()`. - fn len(&self) -> usize { - self.as_ref().len() - } + fn len(&self) -> usize; /// Returns whether the builder is currently empty. - /// - /// This is a convenience method and identical to - /// `self.as_ref().is_empty()`. - fn is_empty(&self) -> bool { - self.as_ref().is_empty() - } + fn is_empty(&self) -> bool; /// Appends all data or nothing. /// @@ -561,6 +556,7 @@ pub trait OctetsBuilder: AsRef<[u8]> + AsMut<[u8]> + Sized { /// builder will be truncated to its previous length. fn u16_len_prefixed(&mut self, op: F) -> Result<(), ShortBuf> where + Self: AsMut<[u8]>, F: FnOnce(&mut Self) -> Result<(), ShortBuf>, { let pos = self.len(); @@ -599,6 +595,14 @@ impl<'a, T: OctetsBuilder> OctetsBuilder for &'a mut T { fn freeze(self) -> Self::Octets { self } + + fn len(&self) -> usize { + OctetsBuilder::len(*self) + } + + fn is_empty(&self) -> bool { + OctetsBuilder::is_empty(*self) + } } #[cfg(feature = "std")] @@ -617,6 +621,53 @@ impl OctetsBuilder for Vec { fn freeze(self) -> Self::Octets { self } + + fn len(&self) -> usize { + Vec::len(self) + } + + fn is_empty(&self) -> bool { + Vec::is_empty(self) + } +} + +#[cfg(feature = "std")] +impl<'a> OctetsBuilder for Cow<'a, [u8]> { + type Octets = Self; + + fn append_slice(&mut self, slice: &[u8]) -> Result<(), ShortBuf> { + if let Cow::Owned(ref mut vec) = *self { + vec.extend_from_slice(slice); + } else { + let mut vec = mem::replace(self, Cow::Borrowed(b"")).into_owned(); + vec.extend_from_slice(slice); + *self = Cow::Owned(vec); + } + Ok(()) + } + + fn truncate(&mut self, len: usize) { + match *self { + Cow::Owned(ref mut vec) => vec.truncate(len), + Cow::Borrowed(ref mut slice) => { + if len < slice.len() { + *slice = &slice[..len] + } + } + } + } + + fn freeze(self) -> Self::Octets { + self + } + + fn len(&self) -> usize { + self.as_ref().len() + } + + fn is_empty(&self) -> bool { + self.as_ref().is_empty() + } } #[cfg(feature = "bytes")] @@ -635,6 +686,14 @@ impl OctetsBuilder for BytesMut { fn freeze(self) -> Self::Octets { self.freeze() } + + fn len(&self) -> usize { + Self::len(self) + } + + fn is_empty(&self) -> bool { + Self::is_empty(self) + } } #[cfg(feature = "smallvec")] @@ -653,6 +712,14 @@ impl> OctetsBuilder for SmallVec { fn freeze(self) -> Self::Octets { self } + + fn len(&self) -> usize { + Self::len(self) + } + + fn is_empty(&self) -> bool { + Self::is_empty(self) + } } #[cfg(feature = "heapless")] @@ -670,6 +737,14 @@ impl OctetsBuilder for heapless::Vec { fn freeze(self) -> Self::Octets { self } + + fn len(&self) -> usize { + self.as_slice().len() + } + + fn is_empty(&self) -> bool { + self.as_slice().is_empty() + } } //------------ EmptyBuilder -------------------------------------------------- @@ -1720,7 +1795,7 @@ pub trait Compose { /// If the representation doesn’t fit into the builder, returns an error. /// In this case the target is considered undefined. If it is supposed to /// be reused, it needs to be reset specifically. - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf>; @@ -1730,7 +1805,7 @@ pub trait Compose { /// If the representation doesn’t fit into the builder, returns an error. /// In this case the target is considered undefined. If it is supposed to /// be reused, it needs to be reset specifically. - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1739,14 +1814,14 @@ pub trait Compose { } impl<'a, C: Compose + ?Sized> Compose for &'a C { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { (*self).compose(target) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1755,7 +1830,7 @@ impl<'a, C: Compose + ?Sized> Compose for &'a C { } impl Compose for i8 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1764,7 +1839,7 @@ impl Compose for i8 { } impl Compose for u8 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1773,7 +1848,7 @@ impl Compose for u8 { } impl Compose for i16 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1782,7 +1857,7 @@ impl Compose for i16 { } impl Compose for u16 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1791,7 +1866,7 @@ impl Compose for u16 { } impl Compose for i32 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1800,7 +1875,7 @@ impl Compose for i32 { } impl Compose for u32 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1809,7 +1884,7 @@ impl Compose for u32 { } impl Compose for Ipv4Addr { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1818,7 +1893,7 @@ impl Compose for Ipv4Addr { } impl Compose for Ipv6Addr { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1946,6 +2021,14 @@ macro_rules! octets_array { fn freeze(self) -> Self::Octets { self } + + fn len(&self) -> usize { + self.len + } + + fn is_empty(&self) -> bool { + self.len == 0 + } } impl $crate::base::octets::EmptyBuilder for $name { diff --git a/src/base/opt/macros.rs b/src/base/opt/macros.rs index 655d6efd..bf049e51 100644 --- a/src/base/opt/macros.rs +++ b/src/base/opt/macros.rs @@ -40,7 +40,7 @@ macro_rules! opt_types { //--- Compose impl> Compose for AllOptData { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { match *self { diff --git a/src/base/opt/mod.rs b/src/base/opt/mod.rs index 66150d6d..538afe01 100644 --- a/src/base/opt/mod.rs +++ b/src/base/opt/mod.rs @@ -169,7 +169,7 @@ impl Parse for Opt { } impl> Compose for Opt { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -314,7 +314,7 @@ impl Default for OptHeader { } impl Compose for OptHeader { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -498,7 +498,7 @@ impl> Parse for OptionHeader { } impl Compose for OptionHeader { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -748,7 +748,7 @@ impl> AsMut<[u8]> for UnknownOptData { //--- Compose impl> Compose for UnknownOptData { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc5001.rs b/src/base/opt/rfc5001.rs index 880068b0..1319173a 100644 --- a/src/base/opt/rfc5001.rs +++ b/src/base/opt/rfc5001.rs @@ -26,10 +26,14 @@ impl Nsid { } impl Nsid<()> { - pub fn push>( + pub fn push( builder: &mut OptBuilder, data: &Data - ) -> Result<(), ShortBuf> { + ) -> Result<(), ShortBuf> + where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + Data: AsRef<[u8]>, + { let data = data.as_ref(); assert!(data.len() <= core::u16::MAX as usize); builder.push_raw_option(OptionCode::Nsid, |target| { @@ -56,7 +60,7 @@ impl CodeOptData for Nsid { impl> Compose for Nsid { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc6975.rs b/src/base/opt/rfc6975.rs index facb8d6c..8a1a0a97 100644 --- a/src/base/opt/rfc6975.rs +++ b/src/base/opt/rfc6975.rs @@ -30,7 +30,7 @@ macro_rules! option_type { } impl $name<()> { - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, algs: &[SecAlg] ) -> Result<(), ShortBuf> { @@ -61,7 +61,7 @@ macro_rules! option_type { } impl> Compose for $name { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc7314.rs b/src/base/opt/rfc7314.rs index f54bd889..57b91a7c 100644 --- a/src/base/opt/rfc7314.rs +++ b/src/base/opt/rfc7314.rs @@ -18,7 +18,7 @@ impl Expire { Expire(expire) } - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, expire: Option ) -> Result<(), ShortBuf> { @@ -54,7 +54,7 @@ impl> Parse for Expire { } impl Compose for Expire { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc7828.rs b/src/base/opt/rfc7828.rs index b1ac22e2..b47c11d9 100644 --- a/src/base/opt/rfc7828.rs +++ b/src/base/opt/rfc7828.rs @@ -18,7 +18,7 @@ impl TcpKeepalive { TcpKeepalive(timeout) } - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, timeout: u16 ) -> Result<(), ShortBuf> { @@ -44,7 +44,7 @@ impl> Parse for TcpKeepalive { } impl Compose for TcpKeepalive { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc7830.rs b/src/base/opt/rfc7830.rs index f6b2d47b..5f0b15ef 100644 --- a/src/base/opt/rfc7830.rs +++ b/src/base/opt/rfc7830.rs @@ -35,14 +35,14 @@ impl Padding { Padding { len, mode } } - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, len: u16, ) -> Result<(), ShortBuf> { Self::push_with_mode(builder, len, PaddingMode::Zero) } - pub fn push_with_mode( + pub fn push_with_mode + AsMut<[u8]>>( builder: &mut OptBuilder, len: u16, mode: PaddingMode @@ -81,7 +81,7 @@ impl> Parse for Padding { } impl Compose for Padding { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc7871.rs b/src/base/opt/rfc7871.rs index e0354d7a..22883c85 100644 --- a/src/base/opt/rfc7871.rs +++ b/src/base/opt/rfc7871.rs @@ -36,7 +36,7 @@ impl ClientSubnet { } } - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, source_prefix_len: u8, scope_prefix_len: u8, @@ -134,7 +134,7 @@ impl> Parse for ClientSubnet { } impl Compose for ClientSubnet { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc7873.rs b/src/base/opt/rfc7873.rs index 64b51549..4cce8f46 100644 --- a/src/base/opt/rfc7873.rs +++ b/src/base/opt/rfc7873.rs @@ -18,7 +18,7 @@ impl Cookie { Cookie(cookie) } - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, cookie: [u8; 8] ) -> Result<(), ShortBuf> { @@ -47,7 +47,7 @@ impl> Parse for Cookie { impl Compose for Cookie { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc7901.rs b/src/base/opt/rfc7901.rs index 0eeeafbd..a5c11533 100644 --- a/src/base/opt/rfc7901.rs +++ b/src/base/opt/rfc7901.rs @@ -23,10 +23,14 @@ impl Chain { Chain { start } } - pub fn push( + pub fn push( builder: &mut OptBuilder, start: &N - ) -> Result<(), ShortBuf> { + ) -> Result<(), ShortBuf> + where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + N: ToDname, + { builder.push_raw_option(OptionCode::Chain, |target| { target.append_all(|target| { for label in start.iter_labels() { @@ -56,7 +60,7 @@ impl Parse for Chain { } impl> Compose for Chain { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/opt/rfc8145.rs b/src/base/opt/rfc8145.rs index a194c82a..e33ab34d 100644 --- a/src/base/opt/rfc8145.rs +++ b/src/base/opt/rfc8145.rs @@ -22,7 +22,7 @@ impl KeyTag { KeyTag { octets } } - pub fn push( + pub fn push + AsMut<[u8]>>( builder: &mut OptBuilder, tags: &[u16] ) -> Result<(), ShortBuf> { @@ -70,7 +70,7 @@ impl Parse for KeyTag { } impl> Compose for KeyTag { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/base/question.rs b/src/base/question.rs index 09632056..a8efdf74 100644 --- a/src/base/question.rs +++ b/src/base/question.rs @@ -214,7 +214,7 @@ impl Parse for Question> { } impl Compose for Question { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -225,7 +225,7 @@ impl Compose for Question { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -287,7 +287,7 @@ pub trait AsQuestion { fn qclass(&self) -> Class; /// Produces the encoding of the question. - fn compose_question( + fn compose_question>( &self, target: &mut T, ) -> Result<(), ShortBuf> @@ -302,7 +302,7 @@ pub trait AsQuestion { } /// Produces the canoncial encoding of the question. - fn compose_question_canonical( + fn compose_question_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> diff --git a/src/base/record.rs b/src/base/record.rs index 90ee5b30..156c6103 100644 --- a/src/base/record.rs +++ b/src/base/record.rs @@ -334,7 +334,7 @@ where } impl Compose for Record { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -347,7 +347,7 @@ impl Compose for Record { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -434,7 +434,7 @@ pub trait AsRecord { fn data(&self) -> &Self::Data; /// Produces the encoded record. - fn compose_record( + fn compose_record>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -448,7 +448,7 @@ pub trait AsRecord { } /// Produces the canonically encoded record. - fn compose_record_canonical( + fn compose_record_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -775,7 +775,7 @@ impl Parse for RecordHeader> { } impl Compose for RecordHeader { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -788,7 +788,7 @@ impl Compose for RecordHeader { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/serial.rs b/src/base/serial.rs index 81d92957..99b19ecf 100644 --- a/src/base/serial.rs +++ b/src/base/serial.rs @@ -207,7 +207,7 @@ impl> Parse for Serial { } impl Compose for Serial { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/base/str.rs b/src/base/str.rs index ededb23c..0f55354a 100644 --- a/src/base/str.rs +++ b/src/base/str.rs @@ -6,6 +6,13 @@ use super::octets::ParseError; use core::fmt; +//------------ String -------------------------------------------------------- + +/// An immutable, UTF-8 encoded string atop some octets sequence. +pub struct String(Octets); + +// XXX Add all the things! + //------------ Symbol -------------------------------------------------------- /// The master file representation of a single character. @@ -174,6 +181,36 @@ impl fmt::Display for Symbol { } } +//------------ Symbols ------------------------------------------------------- + +/// An iterator over the symbols in a char sequence. +#[derive(Clone, Debug)] +pub struct Symbols { + /// The chars of the sequence. + /// + /// This is an option so we can fuse the iterator on error. + chars: Option, +} + +impl Symbols { + /// Creates a new symbols iterator atop a char iterator. + pub fn new(chars: Chars) -> Self { + Symbols { chars: Some(chars) } + } +} + +impl> Iterator for Symbols { + type Item = Symbol; + + fn next(&mut self) -> Option { + if let Ok(res) = Symbol::from_chars(self.chars.as_mut()?) { + return res; + } + self.chars = None; + None + } +} + //============ Error Types =================================================== //------------ SymbolError --------------------------------------------------- @@ -220,3 +257,10 @@ impl fmt::Display for BadSymbol { #[cfg(feature = "std")] impl std::error::Error for BadSymbol {} + +#[cfg(feature = "std")] +impl From for std::io::Error { + fn from(err: BadSymbol) -> Self { + std::io::Error::new(std::io::ErrorKind::Other, err) + } +} diff --git a/src/rdata/macros.rs b/src/rdata/macros.rs index 3190506a..9a88fa25 100644 --- a/src/rdata/macros.rs +++ b/src/rdata/macros.rs @@ -241,7 +241,7 @@ macro_rules! rdata_types { impl $crate::base::octets::Compose for ZoneRecordData where O: AsRef<[u8]>, N: $crate::base::name::ToDname { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), $crate::base::octets::ShortBuf> { @@ -257,10 +257,11 @@ macro_rules! rdata_types { } } - fn compose_canonical( + fn compose_canonical( &self, target: &mut T - ) -> Result<(), $crate::base::octets::ShortBuf> { + ) -> Result<(), $crate::base::octets::ShortBuf> + where T: $crate::base::octets::OctetsBuilder + AsMut<[u8]> { match *self { $( $( $( ZoneRecordData::$mtype(ref inner) => { @@ -664,7 +665,7 @@ macro_rules! rdata_types { impl $crate::base::octets::Compose for AllRecordData where O: AsRef<[u8]>, N: $crate::base::name::ToDname { - fn compose( + fn compose>( &self, buf: &mut T ) -> Result<(), $crate::base::octets::ShortBuf> { @@ -684,10 +685,11 @@ macro_rules! rdata_types { } } - fn compose_canonical( + fn compose_canonical( &self, buf: &mut T - ) -> Result<(), $crate::base::octets::ShortBuf> { + ) -> Result<(), $crate::base::octets::ShortBuf> + where T: $crate::base::octets::OctetsBuilder + AsMut<[u8]> { match *self { $( $( $( AllRecordData::$mtype(ref inner) => { @@ -967,14 +969,14 @@ macro_rules! dname_type { } impl Compose for $target { - fn compose( + fn compose>( &self, target: &mut T ) -> Result<(), ShortBuf> { target.append_compressed_dname(&self.$field) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T ) -> Result<(), ShortBuf> { diff --git a/src/rdata/rfc1035.rs b/src/rdata/rfc1035.rs index afcfe90f..6d60dcd1 100644 --- a/src/rdata/rfc1035.rs +++ b/src/rdata/rfc1035.rs @@ -116,7 +116,7 @@ impl> Parse for A { } impl Compose for A { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -324,7 +324,7 @@ impl Parse for Hinfo { } impl> Compose for Hinfo { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -551,7 +551,7 @@ impl Parse for Minfo> { } impl Compose for Minfo { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -561,7 +561,7 @@ impl Compose for Minfo { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -726,7 +726,7 @@ impl Parse for Mx> { } impl Compose for Mx { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -736,7 +736,7 @@ impl Compose for Mx { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -912,7 +912,7 @@ impl Parse for Null { } impl> Compose for Null { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1223,7 +1223,7 @@ impl Parse for Soa> { } impl Compose for Soa { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1238,7 +1238,7 @@ impl Compose for Soa { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1309,7 +1309,7 @@ impl Txt { /// Creates a new Txt record from a single character string. pub fn from_slice(text: &[u8]) -> Result where - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { let mut builder = TxtBuilder::::new(); builder.append_slice(text)?; @@ -1489,7 +1489,7 @@ impl Parse for Txt { } impl> Compose for Txt { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1589,7 +1589,7 @@ where impl<'de, Octets> serde::Deserialize<'de> for Txt where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: EmptyBuilder, + ::Builder: EmptyBuilder + AsMut<[u8]>, { fn deserialize>( deserializer: D, @@ -1602,7 +1602,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = Txt; @@ -1667,7 +1667,7 @@ where where Octets: FromBuilder + DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + AsMut<[u8]>, { type Value = Txt; @@ -1756,7 +1756,7 @@ impl TxtBuilder { } } -impl TxtBuilder { +impl> TxtBuilder { pub fn append_slice(&mut self, mut slice: &[u8]) -> Result<(), ShortBuf> { if let Some(start) = self.start { let left = 255 - (self.builder.len() - (start + 1)); diff --git a/src/rdata/rfc2782.rs b/src/rdata/rfc2782.rs index 962c5470..e1a78f41 100644 --- a/src/rdata/rfc2782.rs +++ b/src/rdata/rfc2782.rs @@ -175,7 +175,7 @@ impl Parse for Srv> { } impl Compose for Srv { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -187,7 +187,7 @@ impl Compose for Srv { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/rdata/rfc2845.rs b/src/rdata/rfc2845.rs index 3758ea17..d19e1c74 100644 --- a/src/rdata/rfc2845.rs +++ b/src/rdata/rfc2845.rs @@ -407,7 +407,7 @@ impl Parse for Tsig> { } impl, N: Compose> Compose for Tsig { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -559,7 +559,7 @@ impl> Parse for Time48 { } impl Compose for Time48 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/rdata/rfc3596.rs b/src/rdata/rfc3596.rs index 430da14f..1400d254 100644 --- a/src/rdata/rfc3596.rs +++ b/src/rdata/rfc3596.rs @@ -89,7 +89,7 @@ impl> Parse for Aaaa { } impl Compose for Aaaa { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/rdata/rfc4034.rs b/src/rdata/rfc4034.rs index 82793418..9077ca21 100644 --- a/src/rdata/rfc4034.rs +++ b/src/rdata/rfc4034.rs @@ -286,7 +286,7 @@ impl Parse for Dnskey { } impl> Compose for Dnskey { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -421,7 +421,7 @@ where //--- Compose impl Compose for ProtoRrsig { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -437,7 +437,7 @@ impl Compose for ProtoRrsig { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -766,7 +766,7 @@ impl Parse for Rrsig> { } impl, Name: Compose> Compose for Rrsig { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -783,7 +783,7 @@ impl, Name: Compose> Compose for Rrsig { }) } - fn compose_canonical( + fn compose_canonical>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -886,7 +886,8 @@ impl RtypeRecordData for Rrsig { deserialize = " Octets: FromBuilder + crate::base::octets::DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + + AsRef<[u8]> + AsMut<[u8]>, Name: serde::Deserialize<'de>, ", )) @@ -1025,7 +1026,7 @@ impl Parse for Nsec> { } impl, Name: Compose> Compose for Nsec { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1266,7 +1267,7 @@ impl Parse for Ds { } impl> Compose for Ds { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1504,7 +1505,7 @@ impl Parse for RtypeBitmap { } impl> Compose for RtypeBitmap { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -1596,7 +1597,8 @@ where impl<'de, Octets> serde::Deserialize<'de> for RtypeBitmap where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: EmptyBuilder, + ::Builder: + EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>, { fn deserialize>( deserializer: D, @@ -1608,8 +1610,10 @@ where impl<'de, Octets> serde::de::Visitor<'de> for InnerVisitor<'de, Octets> where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: - OctetsBuilder + EmptyBuilder, + ::Builder: OctetsBuilder + + EmptyBuilder + + AsRef<[u8]> + + AsMut<[u8]>, { type Value = RtypeBitmap; @@ -1656,8 +1660,10 @@ where impl<'de, Octets> serde::de::Visitor<'de> for NewtypeVisitor where Octets: FromBuilder + DeserializeOctets<'de>, - ::Builder: - OctetsBuilder + EmptyBuilder, + ::Builder: OctetsBuilder + + EmptyBuilder + + AsRef<[u8]> + + AsMut<[u8]>, { type Value = RtypeBitmap; @@ -1723,7 +1729,10 @@ impl RtypeBitmapBuilder> { } } -impl RtypeBitmapBuilder { +impl RtypeBitmapBuilder +where + Builder: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, +{ pub fn add(&mut self, rtype: Rtype) -> Result<(), ShortBuf> { let (block, octet, bit) = split_rtype(rtype); let block = self.get_block(block)?; @@ -1736,7 +1745,7 @@ impl RtypeBitmapBuilder { fn get_block(&mut self, block: u8) -> Result<&mut [u8], ShortBuf> { let mut pos = 0; - while pos < self.buf.as_ref().len() { + while pos < self.buf.len() { match self.buf.as_ref()[pos].cmp(&block) { Ordering::Equal => { return Ok(&mut self.buf.as_mut()[pos..pos + 34]) diff --git a/src/rdata/rfc5155.rs b/src/rdata/rfc5155.rs index 3c3ae557..24575f8b 100644 --- a/src/rdata/rfc5155.rs +++ b/src/rdata/rfc5155.rs @@ -35,7 +35,8 @@ use core::{fmt, hash, ops, str}; deserialize = " Octets: FromBuilder + crate::base::octets::DeserializeOctets<'de>, ::Builder: - OctetsBuilder + EmptyBuilder, + OctetsBuilder + EmptyBuilder + + AsRef<[u8]> + AsMut<[u8]>, ", )) )] @@ -246,7 +247,7 @@ impl Parse for Nsec3 { } impl> Compose for Nsec3 { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -494,7 +495,7 @@ impl Parse for Nsec3param { } impl> Compose for Nsec3param { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -752,7 +753,7 @@ impl Parse for Nsec3Salt { } impl + ?Sized> Compose for Nsec3Salt { - fn compose( + fn compose>( &self, target: &mut Target, ) -> Result<(), ShortBuf> { @@ -1097,7 +1098,7 @@ impl Parse for OwnerHash { } impl + ?Sized> Compose for OwnerHash { - fn compose( + fn compose>( &self, target: &mut Target, ) -> Result<(), ShortBuf> { diff --git a/src/rdata/rfc7344.rs b/src/rdata/rfc7344.rs index e31ce8d3..3087c8df 100644 --- a/src/rdata/rfc7344.rs +++ b/src/rdata/rfc7344.rs @@ -189,7 +189,7 @@ impl Parse for Cdnskey { } impl> Compose for Cdnskey { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -433,7 +433,7 @@ impl Parse for Cds { } impl> Compose for Cds { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/rdata/svcb.rs b/src/rdata/svcb.rs index 4eaa2117..20af9e6b 100644 --- a/src/rdata/svcb.rs +++ b/src/rdata/svcb.rs @@ -89,7 +89,9 @@ impl $name { sorter: self.sorter, } } +} +impl, N> $name { /// Push a parameter into the builder. pub fn push>( &mut self, @@ -123,7 +125,7 @@ impl Parse for $name> { } impl, N: Compose> Compose for $name { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -151,7 +153,7 @@ impl, N: Compose> Compose for $name { impl, N: Compose> $name { /// Compose without checking for the order of parameters. - pub fn compose_unchecked( + pub fn compose_unchecked>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -355,7 +357,7 @@ pub mod param { } impl> Compose for AllParams { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -452,7 +454,7 @@ pub mod param { } impl> Compose for $name { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -535,7 +537,7 @@ pub mod param { octets_wrapper!(Mandatory, MandatoryIter); - impl Mandatory { + impl> Mandatory { pub fn push(&mut self, key: SvcbParamKey) -> Result<(), ShortBuf> { u16::from(key).compose(&mut self.0) } @@ -572,7 +574,7 @@ pub mod param { octets_wrapper!(Alpn, AlpnIter); - impl Alpn { + impl> Alpn { pub fn push>( &mut self, name: O, @@ -636,7 +638,7 @@ pub mod param { } impl Compose for NoDefaultAlpn { - fn compose( + fn compose>( &self, _target: &mut T, ) -> Result<(), ShortBuf> { @@ -676,7 +678,7 @@ pub mod param { } impl Compose for Port { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { @@ -827,7 +829,7 @@ pub mod param { } impl> Compose for Unknown { - fn compose( + fn compose>( &self, target: &mut T, ) -> Result<(), ShortBuf> { diff --git a/src/sign/records.rs b/src/sign/records.rs index 8c576505..82c0d41e 100644 --- a/src/sign/records.rs +++ b/src/sign/records.rs @@ -175,7 +175,7 @@ impl SortedRecords { N: ToDname + Clone, D: RecordData, Octets: FromBuilder, - Octets::Builder: EmptyBuilder, + Octets::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>, ApexName: ToDname, { let mut res = Vec::new(); diff --git a/src/tsig/mod.rs b/src/tsig/mod.rs index d4c14bd3..34bff363 100644 --- a/src/tsig/mod.rs +++ b/src/tsig/mod.rs @@ -303,7 +303,7 @@ impl Key { /// /// The method fails if the TSIG record doesn’t fit into the message /// anymore, in which case the builder is returned unharmed. - fn complete_message( + fn complete_message + AsMut<[u8]>>( &self, message: &mut AdditionalBuilder, variables: &Variables, @@ -431,7 +431,7 @@ impl> ClientTransaction { /// recommended default value for _fudge:_ 300 seconds. /// /// [`request_with_fudge`]: #method.request_with_fudge - pub fn request( + pub fn request + AsMut<[u8]>>( key: K, message: &mut AdditionalBuilder, ) -> Result { @@ -457,11 +457,14 @@ impl> ClientTransaction { /// the untouched message. /// /// [`request`]: #method.request - pub fn request_with_fudge( + pub fn request_with_fudge( key: K, message: &mut AdditionalBuilder, fudge: u16, - ) -> Result { + ) -> Result + where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + { let variables = Variables::new(Time48::now(), fudge, TsigRcode::NoError, None); let (mut context, mac) = SigningContext::request( @@ -581,7 +584,7 @@ impl> ServerTransaction { /// If appending the TSIG record fails, which can only happen if there /// isn’t enough space left, it returns the builder unchanged as the /// error case. - pub fn answer( + pub fn answer + AsMut<[u8]>>( self, message: &mut AdditionalBuilder, ) -> Result<(), ShortBuf> { @@ -596,11 +599,14 @@ impl> ServerTransaction { /// The default, suggested by the RFC, is 300. /// /// [`answer`]: #method.answer - pub fn answer_with_fudge( + pub fn answer_with_fudge( self, message: &mut AdditionalBuilder, fudge: u16, - ) -> Result<(), ShortBuf> { + ) -> Result<(), ShortBuf> + where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + { let variables = Variables::new(Time48::now(), fudge, TsigRcode::NoError, None); let (mac, key) = @@ -661,7 +667,7 @@ impl> ClientSequence { /// returns the builder untouched as the error case. Otherwise, it will /// freeze the message and return both it and a new value of a client /// sequence. - pub fn request( + pub fn request + AsMut<[u8]>>( key: K, message: &mut AdditionalBuilder, ) -> Result { @@ -677,11 +683,14 @@ impl> ClientSequence { /// seconds. /// /// [`request`]: #method.request - pub fn request_with_fudge( + pub fn request_with_fudge( key: K, message: &mut AdditionalBuilder, fudge: u16, - ) -> Result { + ) -> Result + where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + { let variables = Variables::new(Time48::now(), fudge, TsigRcode::NoError, None); let (mut context, mac) = SigningContext::request( @@ -889,7 +898,7 @@ impl> ServerSequence { /// it attempts to add a TSIG record to the additional section, if that /// fails because there wasn’t enough space in the builder, returns the /// unchanged builder as an error. - pub fn answer( + pub fn answer + AsMut<[u8]>>( &mut self, message: &mut AdditionalBuilder, ) -> Result<(), ShortBuf> { @@ -901,11 +910,14 @@ impl> ServerSequence { /// This is nearly identical to [`answer`][Self::answer] except that it /// allows to specify the ‘fudge’ which declares the number of seconds /// the receiver’s clock may be off from this systems current time. - pub fn answer_with_fudge( + pub fn answer_with_fudge( &mut self, message: &mut AdditionalBuilder, fudge: u16, - ) -> Result<(), ShortBuf> { + ) -> Result<(), ShortBuf> + where + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, + { let variables = Variables::new(Time48::now(), fudge, TsigRcode::NoError, None); let mac = if self.first { @@ -1383,7 +1395,7 @@ impl Variables { } /// Produces a TSIG record from this value and some more data. - fn push_tsig( + fn push_tsig>( &self, key: &Key, hmac: &[u8], @@ -1628,13 +1640,15 @@ impl ServerError { } impl> ServerError { - pub fn build_message, Target: OctetsBuilder>( + pub fn build_message( self, msg: &Message, builder: MessageBuilder, ) -> Result, ShortBuf> where + Octets: AsRef<[u8]>, for<'a> &'a Octets: OctetsRef, + Target: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]>, { let builder = builder.start_answer(msg, Rcode::NotAuth)?; let mut builder = builder.additional(); diff --git a/src/validate.rs b/src/validate.rs index 972e21dc..c89abc60 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -106,7 +106,11 @@ pub trait RrsigExt: Compose { /// the received RRset due to DNS name compression, decremented TTLs, or /// wildcard expansion. /// ``` - fn signed_data( + fn signed_data< + N: ToDname, + D: RecordData, + B: OctetsBuilder + AsMut<[u8]>, + >( &self, buf: &mut B, records: &mut [Record], @@ -143,7 +147,11 @@ pub trait RrsigExt: Compose { } impl, Name: Compose> RrsigExt for Rrsig { - fn signed_data( + fn signed_data< + N: ToDname, + D: RecordData, + B: OctetsBuilder + AsMut<[u8]>, + >( &self, buf: &mut B, records: &mut [Record],