1#![allow(clippy::needless_maybe_sized)]
9
10use super::value::AllValues;
11use crate::base::cmp::CanonicalOrd;
12use crate::base::iana::SvcParamKey;
13use crate::base::scan::Symbol;
14use crate::base::wire::{Compose, Parse, ParseError};
15use octseq::builder::{EmptyBuilder, FromBuilder, OctetsBuilder, ShortBuf};
16use octseq::octets::{Octets, OctetsFrom, OctetsInto};
17use octseq::parse::{Parser, ShortInput};
18use core::{cmp, fmt, hash, mem};
19use core::cmp::Ordering;
20use core::marker::PhantomData;
21
22#[derive(Clone, Default)]
71#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
72#[repr(transparent)]
73pub struct SvcParams<Octs: ?Sized> {
74 #[cfg_attr(
75 feature = "serde",
76 serde(
77 serialize_with =
78 "octseq::serde::SerializeOctets::serialize_octets",
79 deserialize_with =
80 "octseq::serde::DeserializeOctets::deserialize_octets",
81 bound(
82 serialize = "Octs: octseq::serde::SerializeOctets",
83 deserialize =
84 "Octs: octseq::serde::DeserializeOctets<'de> + Sized",
85 )
86 )
87 )]
88 octets: Octs,
89}
90
91impl<Octs> SvcParams<Octs> {
92 pub fn from_octets(octets: Octs) -> Result<Self, SvcParamsError>
99 where Octs: AsRef<[u8]> {
100 SvcParams::check_slice(octets.as_ref())?;
101 Ok(unsafe { Self::from_octets_unchecked(octets) })
102 }
103
104 pub unsafe fn from_octets_unchecked(octets: Octs) -> Self {
111 SvcParams { octets }
112 }
113}
114
115impl SvcParams<[u8]> {
116 pub fn from_slice(slice: &[u8]) -> Result<&Self, SvcParamsError> {
123 SvcParams::check_slice(slice)?;
124 Ok(unsafe { Self::from_slice_unchecked(slice) })
125 }
126
127 #[must_use]
134 pub unsafe fn from_slice_unchecked(slice: &[u8]) -> &Self {
135 mem::transmute(slice)
137 }
138
139 fn check_slice(slice: &[u8]) -> Result<(), SvcParamsError> {
141 let mut parser = Parser::from_ref(slice);
142 let mut last_key = None;
143 while parser.remaining() > 0 {
144 let key = u16::parse(&mut parser)?;
145 if let Some(last_key) = last_key {
146 if key <= last_key {
147 Err(ParseError::form_error("unordered SVCB params"))?;
148 }
149 }
150 last_key = Some(key);
151 let len = u16::parse(&mut parser)?;
152 parser.advance(len.into())?;
153 }
154 Ok(())
155 }
156}
157
158impl<Octs> SvcParams<Octs> {
159 pub fn from_values<F>(op: F) -> Result<Self, PushError>
165 where
166 Octs: FromBuilder,
167 <Octs as FromBuilder>::Builder:
168 AsRef<[u8]> + OctetsBuilder + EmptyBuilder,
169 F: FnOnce(
170 &mut SvcParamsBuilder<<Octs as FromBuilder>::Builder>
171 ) -> Result<(), PushError>,
172 {
173 let mut res = SvcParamsBuilder::empty();
174 op(&mut res)?;
175 res.freeze().map_err(Into::into)
176 }
177}
178
179impl<Octs: AsRef<[u8]>> SvcParams<Octs> {
180 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized + 'a>(
182 parser: &mut Parser<'a, Src>
183 ) -> Result<Self, ParseError> {
184 Self::from_octets(
185 parser.parse_octets(parser.remaining())?
186 ).map_err(Into::into)
187 }
188}
189
190impl<Octs: ?Sized> SvcParams<Octs> {
191 pub fn as_octets(&self) -> &Octs {
193 &self.octets
194 }
195}
196
197impl<Octs: AsRef<[u8]> + ?Sized> SvcParams<Octs> {
198 pub fn as_slice(&self) -> &[u8] {
200 self.octets.as_ref()
201 }
202
203 pub fn for_slice(&self) -> &SvcParams<[u8]> {
205 unsafe { SvcParams::from_slice_unchecked(self.octets.as_ref()) }
206 }
207
208 pub fn len(&self) -> usize {
210 self.octets.as_ref().len()
211 }
212
213 pub fn is_empty(&self) -> bool {
215 self.octets.as_ref().is_empty()
216 }
217
218 pub fn first<'s, Value>(&'s self) -> Option<Value>
228 where
229 Octs: Octets,
230 Value: ParseSvcParamValue<'s, Octs>,
231 {
232 self.iter::<Value>().next().and_then(Result::ok)
233 }
234
235 pub fn iter<Value>(&self) -> ValueIter<Octs, Value> {
237 ValueIter::new(self.as_octets())
238 }
239
240 pub fn iter_all(&self) -> ValueIter<Octs, AllValues<Octs>>
242 where Octs: Sized {
243 self.iter()
244 }
245
246 pub fn iter_raw(
248 &self
249 ) -> impl Iterator<Item = UnknownSvcParam<Octs::Range<'_>>>
250 where Octs: Octets + Sized {
251 self.iter().map(|item| item.expect("parsing cannot have failed"))
252 }
253
254 pub fn compose<Target: OctetsBuilder + ?Sized>(
256 &self, target: &mut Target
257 ) -> Result<(), Target::AppendError> {
258 target.append_slice(self.octets.as_ref())
259 }
260}
261
262impl<SrcOcts, Octs> OctetsFrom<SvcParams<SrcOcts>> for SvcParams<Octs>
265where Octs: OctetsFrom<SrcOcts> {
266 type Error = Octs::Error;
267
268 fn try_octets_from(
269 src: SvcParams<SrcOcts>
270 ) -> Result<Self, Self::Error> {
271 Ok(unsafe {
272 SvcParams::from_octets_unchecked(src.octets.try_octets_into()?)
273 })
274 }
275}
276
277impl<Octs, OtherOcts> PartialEq<SvcParams<OtherOcts>> for SvcParams<Octs>
280where
281 Octs: AsRef<[u8]> + ?Sized,
282 OtherOcts: AsRef<[u8]> + ?Sized,
283{
284 fn eq(&self, other: &SvcParams<OtherOcts>) -> bool {
285 self.as_slice().eq(other.as_slice())
286 }
287}
288
289impl<Octs: AsRef<[u8]> + ?Sized> Eq for SvcParams<Octs> { }
290
291impl<Octs: AsRef<[u8]> + ?Sized> hash::Hash for SvcParams<Octs> {
294 fn hash<H: hash::Hasher>(&self, state: &mut H) {
295 self.as_slice().hash(state)
296 }
297}
298
299impl<Octs, OtherOcts> PartialOrd<SvcParams<OtherOcts>> for SvcParams<Octs>
302where
303 Octs: AsRef<[u8]> + ?Sized,
304 OtherOcts: AsRef<[u8]> + ?Sized,
305{
306 fn partial_cmp(
307 &self, other: &SvcParams<OtherOcts>
308 ) -> Option<cmp::Ordering> {
309 self.as_slice().partial_cmp(other.as_slice())
310 }
311}
312
313impl<Octs: AsRef<[u8]> + ?Sized> Ord for SvcParams<Octs> {
314 fn cmp(&self, other: &Self) -> cmp::Ordering {
315 self.as_slice().cmp(other.as_slice())
316 }
317}
318
319impl<Octs, OtherOcts> CanonicalOrd<SvcParams<OtherOcts>> for SvcParams<Octs>
320where
321 Octs: AsRef<[u8]> + ?Sized,
322 OtherOcts: AsRef<[u8]> + ?Sized,
323{
324 fn canonical_cmp(
325 &self, other: &SvcParams<OtherOcts>
326 ) -> cmp::Ordering {
327 self.as_slice().cmp(other.as_slice())
328 }
329}
330
331impl<Octs: Octets + ?Sized> fmt::Display for SvcParams<Octs> {
334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
335 let mut parser = Parser::from_ref(self.as_slice());
336 let mut first = true;
337 while parser.remaining() > 0 {
338 let key = SvcParamKey::parse(
339 &mut parser
340 ).expect("invalid SvcbParam");
341 let len = usize::from(
342 u16::parse(&mut parser).expect("invalid SvcParam")
343 );
344 let mut parser = parser.parse_parser(
345 len
346 ).expect("invalid SvcParam");
347 if first {
348 first = false;
349 }
350 else {
351 f.write_str(" ")?;
352 }
353 write!(
354 f, "{}", super::value::AllValues::parse_any(key, &mut parser)
355 )?;
356 };
357 Ok(())
358 }
359}
360
361impl<Octs: Octets + ?Sized> fmt::Debug for SvcParams<Octs> {
362 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
363 f.debug_tuple("SvcParams").field(
364 &format_args!("{}", self)
365 ).finish()
366 }
367}
368
369
370#[derive(Clone, Debug)]
377pub struct ValueIter<'a, Octs: ?Sized, Value> {
378 parser: Parser<'a, Octs>,
379 marker: PhantomData<Value>,
380}
381
382impl<'a, Octs: AsRef<[u8]> + ?Sized, Value> ValueIter<'a, Octs, Value> {
383 fn new(octets: &'a Octs) -> Self {
384 ValueIter {
385 parser: Parser::from_ref(octets),
386 marker: PhantomData,
387 }
388 }
389
390 fn next_step(&mut self) -> Result<Option<Value>, ParseError>
391 where
392 Octs: Octets,
393 Value: ParseSvcParamValue<'a, Octs>,
394 {
395 let key = SvcParamKey::parse(&mut self.parser)?;
396 let len = usize::from(u16::parse(&mut self.parser)?);
397 let mut parser = self.parser.parse_parser(len)?;
398 let res = Value::parse_value(key, &mut parser)?;
399 if res.is_some() && parser.remaining() > 0 {
400 return Err(ParseError::form_error(
401 "trailing data in SVCB parameter",
402 ));
403 }
404 Ok(res)
405 }
406}
407
408impl<'a, Octs, Value> Iterator for ValueIter<'a, Octs, Value>
409where
410 Octs: Octets + ?Sized,
411 Value: ParseSvcParamValue<'a, Octs>,
412{
413 type Item = Result<Value, ParseError>;
414
415 fn next(&mut self) -> Option<Self::Item> {
416 while self.parser.remaining() > 0 {
417 match self.next_step() {
418 Ok(Some(res)) => return Some(Ok(res)),
419 Ok(None) => { }
420 Err(err) => {
421 self.parser.advance_to_end();
423 return Some(Err(err));
424 }
425 }
426 }
427 None
428 }
429}
430
431pub trait SvcParamValue {
435 fn key(&self) -> SvcParamKey;
437}
438
439pub trait ParseSvcParamValue<'a, Octs: ?Sized>: SvcParamValue + Sized {
441 fn parse_value(
446 key: SvcParamKey, parser: &mut Parser<'a, Octs>,
447 ) -> Result<Option<Self>, ParseError>;
448}
449
450pub trait ComposeSvcParamValue: SvcParamValue {
457 fn compose_len(&self) -> u16;
459
460 fn compose_value<Target: OctetsBuilder + ?Sized>(
462 &self, target: &mut Target,
463 ) -> Result<(), Target::AppendError>;
464}
465
466#[derive(Clone, Debug)]
473pub struct UnknownSvcParam<Octs> {
474 key: SvcParamKey,
476
477 value: Octs,
479}
480
481impl<Octs> UnknownSvcParam<Octs> {
482 pub fn new(key: SvcParamKey, value: Octs) -> Result<Self, LongSvcParam>
486 where Octs: AsRef<[u8]> {
487 LongSvcParam::check_len(value.as_ref().len())?;
488 Ok(unsafe { Self::new_unchecked(key, value) })
489 }
490
491 pub unsafe fn new_unchecked(key: SvcParamKey, value: Octs) -> Self {
498 Self { key, value }
499 }
500}
501
502impl<Octs: AsRef<[u8]>> UnknownSvcParam<Octs> {
503 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
505 key: SvcParamKey,
506 parser: &mut Parser<'a, Src>,
507 ) -> Result<Self, ParseError> {
508 Self::new(
509 key, parser.parse_octets(parser.remaining())?
510 ).map_err(Into::into)
511 }
512
513 pub fn parse_param<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
517 parser: &mut Parser<'a, Src>,
518 ) -> Result<Self, ParseError> {
519 let key = SvcParamKey::parse(parser)?;
520 let len = usize::from(u16::parse(parser)?);
521 let value = parser.parse_octets(len)?;
522 Ok(unsafe { Self::new_unchecked(key, value) })
523 }
524
525 pub fn compose_param<Target: OctetsBuilder + ?Sized>(
529 &self, target: &mut Target
530 ) -> Result<(), Target::AppendError> {
531 self.key.compose(target)?;
532 self.compose_len().compose(target)?;
533 self.compose_value(target)
534 }
535}
536
537impl<Octs> UnknownSvcParam<Octs> {
538 pub fn key(&self) -> SvcParamKey {
540 self.key
541 }
542
543 pub fn value(&self) -> &Octs {
545 &self.value
546 }
547
548 pub fn as_slice(&self) -> &[u8]
550 where Octs: AsRef<[u8]> {
551 self.value.as_ref()
552 }
553
554 pub fn as_slice_mut(&mut self) -> &mut [u8]
556 where Octs: AsMut<[u8]> {
557 self.value.as_mut()
558 }
559}
560
561impl<Octs> AsRef<Octs> for UnknownSvcParam<Octs> {
564 fn as_ref(&self) -> &Octs {
565 self.value()
566 }
567}
568
569impl<Octs: AsRef<[u8]>> AsRef<[u8]> for UnknownSvcParam<Octs> {
570 fn as_ref(&self) -> &[u8] {
571 self.as_slice()
572 }
573}
574
575impl<Octs: AsMut<[u8]>> AsMut<[u8]> for UnknownSvcParam<Octs> {
576 fn as_mut(&mut self) -> &mut [u8] {
577 self.as_slice_mut()
578 }
579}
580
581impl<Octs, OtherOcts> PartialEq<UnknownSvcParam<OtherOcts>>
584for UnknownSvcParam<Octs>
585where
586 Octs: AsRef<[u8]>,
587 OtherOcts: AsRef<[u8]>,
588{
589 fn eq(&self, other: &UnknownSvcParam<OtherOcts>) -> bool {
590 self.as_slice().eq(other.as_slice())
591 }
592}
593
594impl<Octs: AsRef<[u8]>> Eq for UnknownSvcParam<Octs> { }
595
596impl<Octs: AsRef<[u8]>> hash::Hash for UnknownSvcParam<Octs> {
599 fn hash<H: hash::Hasher>(&self, state: &mut H) {
600 self.as_slice().hash(state)
601 }
602}
603
604impl<Octs> SvcParamValue for UnknownSvcParam<Octs> {
607 fn key(&self) -> SvcParamKey {
608 self.key
609 }
610}
611
612impl<'a, Octs: Octets + ?Sized> ParseSvcParamValue<'a, Octs>
613for UnknownSvcParam<Octs::Range<'a>> {
614 fn parse_value(
615 key: SvcParamKey,
616 parser: &mut Parser<'a, Octs>,
617 ) -> Result<Option<Self>, ParseError> {
618 Self::new(
619 key, parser.parse_octets(parser.remaining())?
620 ).map(Some).map_err(Into::into)
621 }
622}
623
624impl<Octs: AsRef<[u8]>> ComposeSvcParamValue for UnknownSvcParam<Octs> {
625 fn compose_len(&self) -> u16 {
626 u16::try_from(self.as_slice().len()).expect("long value")
627 }
628
629 fn compose_value<Target: OctetsBuilder + ?Sized>(
630 &self, target: &mut Target,
631 ) -> Result<(), Target::AppendError> {
632 target.append_slice(self.as_slice())
633 }
634}
635
636impl<Octs: AsRef<[u8]>> fmt::Display for UnknownSvcParam<Octs> {
639 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
640 write!(f, "{}", self.key)?;
641 let slice = self.value.as_ref();
642 if !slice.is_empty() {
643 f.write_str("=")?;
644 for &ch in slice {
645 Symbol::from_octet(ch).fmt(f)?;
646 }
647 }
648 Ok(())
649 }
650}
651
652
653#[derive(Clone, Debug)]
673pub struct SvcParamsBuilder<Octs> {
674 octets: Octs,
676}
677
678impl<Octs> SvcParamsBuilder<Octs> {
679 #[must_use]
681 pub fn empty() -> Self
682 where Octs: EmptyBuilder {
683 Self { octets: Octs::empty() }
684 }
685
686 pub fn from_params<Src: Octets + ?Sized>(
692 params: &SvcParams<Src>
693 ) -> Result<Self, ShortBuf>
694 where Octs: AsRef<[u8]> + OctetsBuilder + EmptyBuilder {
695 let mut octets = Octs::empty();
696 for item in params.iter::<UnknownSvcParam<_>>() {
697 let item = item.expect("invalid SvcParams");
698 let start = u32::try_from(
699 octets.as_ref().len()
700 ).map_err(|_| ShortBuf)?.checked_add(
701 u32::from(u32::COMPOSE_LEN)
702 ).ok_or(ShortBuf)?;
703 octets.append_slice(
704 start.to_ne_bytes().as_ref()
705 ).map_err(Into::into)?;
706 item.compose_param(&mut octets).map_err(Into::into)?;
707 }
708 octets.append_slice(
709 u32::MAX.to_be_bytes().as_ref()
710 ).map_err(Into::into)?;
711 Ok(Self { octets })
712 }
713
714 pub fn push<Value: ComposeSvcParamValue + ?Sized>(
719 &mut self, value: &Value
720 ) -> Result<(), PushError>
721 where Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]> {
722 self.push_raw(
723 value.key(), value.compose_len(), |octs| value.compose_value(octs)
724 )
725 }
726
727 pub(super) fn push_raw(
728 &mut self,
729 key: SvcParamKey,
730 value_len: u16,
731 value: impl FnOnce(&mut Octs) -> Result<(), Octs::AppendError>
732 ) -> Result<(), PushError>
733 where Octs: OctetsBuilder + AsRef<[u8]> + AsMut<[u8]> {
734 if self.octets.as_ref().is_empty() {
736 self.octets.append_slice(
737 &u32::from(u32::COMPOSE_LEN).to_ne_bytes()
738 )?;
739 key.compose(&mut self.octets)?;
740 value_len.compose(&mut self.octets)?;
741 (value)(&mut self.octets)?;
742 u32::MAX.compose(&mut self.octets)?;
743 return Ok(())
744 }
745
746 let start = u32::try_from(self.octets.as_ref().len()).map_err(|_|
749 PushError::ShortBuf
750 )?;
751
752 let mut pre = None;
754 let mut next = None;
755 let mut parser = Parser::from_ref(self.octets.as_ref());
756
757 parser.advance(u32::COMPOSE_LEN.into()).unwrap();
759
760 while parser.remaining() > 0 {
761 let tmp_start = u32::try_from(parser.pos()).unwrap();
762 let tmp = UnknownSvcParam::parse_param(&mut parser).unwrap();
763 let tmp_end = u32::try_from(parser.pos()).unwrap();
764 let tmp_key = tmp.key();
765 match tmp_key.cmp(&key) {
766 Ordering::Equal => return Err(PushError::DuplicateKey),
767 Ordering::Less => {
768 match pre {
769 Some((key, _)) => {
770 if tmp_key > key {
771 pre = Some((tmp_key, tmp_end));
772 }
773 }
774 None => {
775 pre = Some((tmp_key, tmp_end))
776 }
777 }
778 }
779 Ordering::Greater => {
780 match next {
781 Some((key, _)) => {
782 if tmp_key < key {
783 next = Some((tmp_key, tmp_start));
784 }
785 }
786 None => {
787 next = Some((tmp_key, tmp_start))
788 }
789 }
790 }
791 }
792 parser.advance(u32::COMPOSE_LEN.into()).unwrap();
793 }
794
795 key.compose(&mut self.octets)?;
797 value_len.compose(&mut self.octets)?;
798 (value)(&mut self.octets)?;
799
800 self.octets.append_slice(
802 &next.map(|(_, pos)| pos).unwrap_or(u32::MAX).to_ne_bytes()
803 )?;
804
805 let pos = pre.map(|(_, pos)| {
808 usize::try_from(pos).unwrap()
811 }).unwrap_or(0);
812 self.octets.as_mut()[
813 pos..pos + usize::from(u32::COMPOSE_LEN)
814 ].copy_from_slice(
815 &start.to_ne_bytes()
816 );
817
818 Ok(())
819 }
820
821 pub fn freeze<Target>(
828 &self
829 ) -> Result<
830 SvcParams<Target>,
831 <<Target as FromBuilder>::Builder as OctetsBuilder>::AppendError
832 >
833 where
834 Octs: AsRef<[u8]>,
835 Target: FromBuilder,
836 <Target as FromBuilder>::Builder: OctetsBuilder + EmptyBuilder
837 {
838 let mut target = <Target as FromBuilder>::Builder::empty();
839 if !self.octets.as_ref().is_empty() {
840 let mut parser = Parser::from_ref(self.octets.as_ref());
841 loop {
842 let pos = u32::from_ne_bytes(
843 Parse::parse(&mut parser).unwrap()
844 );
845 if pos == u32::MAX {
846 break;
847 }
848 let pos = usize::try_from(pos).unwrap();
849 parser.seek(pos).unwrap();
850 let param = UnknownSvcParam::parse_param(&mut parser).unwrap();
851 param.compose_param(&mut target)?;
852 }
853 }
854 Ok(unsafe {
855 SvcParams::from_octets_unchecked(
856 Target::from_builder(target)
857 )
858 })
859 }
860}
861
862pub struct SvcParamsError(ParseError);
868
869impl From<ShortInput> for SvcParamsError {
870 fn from(err: ShortInput) -> Self {
871 ParseError::from(err).into()
872 }
873}
874
875impl From<ParseError> for SvcParamsError {
876 fn from(err: ParseError) -> Self {
877 SvcParamsError(err)
878 }
879}
880
881impl From<SvcParamsError> for ParseError {
882 fn from(err: SvcParamsError) -> Self {
883 err.0
884 }
885}
886
887#[derive(Clone, Copy, Debug)]
891pub struct LongSvcParam(());
892
893impl LongSvcParam {
894 #[must_use]
895 pub fn as_str(self) -> &'static str {
896 "service parameter too long"
897 }
898
899 pub fn check_len(len: usize) -> Result<(), Self> {
900 if len > usize::from(u16::MAX) {
901 Err(LongSvcParam(()))
902 } else {
903 Ok(())
904 }
905 }
906}
907
908impl From<LongSvcParam> for ParseError {
909 fn from(src: LongSvcParam) -> Self {
910 ParseError::form_error(src.as_str())
911 }
912}
913
914impl fmt::Display for LongSvcParam {
915 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
916 f.write_str(self.as_str())
917 }
918}
919
920#[cfg(feature = "std")]
921impl std::error::Error for LongSvcParam {}
922
923
924#[derive(Clone, Copy, Debug)]
928#[non_exhaustive]
929pub enum PushError {
930 DuplicateKey,
932
933 ShortBuf,
935}
936
937impl<T: Into<ShortBuf>> From<T> for PushError {
938 fn from(_: T) -> Self {
939 PushError::ShortBuf
940 }
941}
942
943impl fmt::Display for PushError {
944 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
945 match self {
946 PushError::DuplicateKey => f.write_str("duplicate key"),
947 PushError::ShortBuf => ShortBuf.fmt(f)
948 }
949 }
950}
951
952#[cfg(feature = "std")]
953impl std::error::Error for PushError {}
954
955
956#[cfg(test)]
959mod test {
960 use super::*;
961 use super::super::value;
962 use octseq::array::Array;
963
964 type Octets512 = Array<512>;
965 type Params512 = SvcParams<Array<512>>;
966 type Builder512 = SvcParamsBuilder<Array<512>>;
967
968 fn octets512(slice: impl AsRef<[u8]>) -> Octets512 {
969 Octets512::try_from(slice.as_ref()).unwrap()
970 }
971
972
973 macro_rules! parse_compose {
978 ( $rdata:expr, [ $( $value:expr )* ] ) => {
979 let mut parser = Parser::from_ref($rdata.as_ref());
981 let params = SvcParams::parse(&mut parser).unwrap();
982
983 let mut param_iter = params.iter_all();
984 $(
985 assert_eq!(
986 param_iter.next().unwrap().unwrap(),
987 AllValues::<Octets512>::from($value)
988 );
989 )*
990 assert_eq!(None, param_iter.next());
991
992 let built = Params512::from_values(|_builder| {
994 $(
995 _builder.push(&$value).unwrap();
996 )*
997 Ok(())
998 }).unwrap();
999 let mut buf = Octets512::new();
1000 built.compose(&mut buf).unwrap();
1001 assert_eq!($rdata.as_ref(), buf.as_ref());
1002 }
1003 }
1004
1005 #[test]
1006 fn test_vectors_alias() {
1007 parse_compose!(b"", []);
1008 }
1009
1010 #[test]
1011 fn test_vectors_port_only() {
1012 parse_compose!(
1013 b"\x00\x03\
1014 \x00\x02\
1015 \x00\x35",
1016 [ value::Port::new(53) ]
1017 );
1018 }
1019
1020 #[test]
1021 fn test_vectors_unknown_param() {
1022 parse_compose!(
1023 b"\x02\x9b\
1024 \x00\x05\
1025 \x68\x65\x6c\x6c\x6f",
1026 [
1027 UnknownSvcParam::new(
1028 0x029b.into(),
1029 octets512(b"hello")
1030 ).unwrap()
1031 ]
1032 );
1033 }
1034
1035 #[test]
1036 fn test_vectors_unknown_param_quote() {
1037 parse_compose!(
1038 b"\x02\x9b\
1039 \x00\x09\
1040 \x68\x65\x6c\x6c\x6f\xd2\x71\x6f\x6f",
1041 [
1042 UnknownSvcParam::new(
1043 0x029b.into(),
1044 octets512(b"\x68\x65\x6c\x6c\x6f\xd2\x71\x6f\x6f"),
1045 ).unwrap()
1046 ]
1047 );
1048 }
1049
1050 #[test]
1051 fn test_vectors_ipv6hint() {
1052 use crate::base::net::Ipv6Addr;
1053 use core::str::FromStr;
1054
1055 parse_compose!(
1056 b"\x00\x06\
1057 \x00\x20\
1058 \x20\x01\x0d\xb8\x00\x00\x00\x00\
1059 \x00\x00\x00\x00\x00\x00\x00\x01\
1060 \x20\x01\x0d\xb8\x00\x00\x00\x00\
1061 \x00\x00\x00\x00\x00\x53\x00\x01",
1062 [
1063 value::Ipv6Hint::<Octets512>::from_addrs([
1064 Ipv6Addr::from_str("2001:db8::1").unwrap(),
1065 Ipv6Addr::from_str("2001:db8::53:1").unwrap(),
1066 ]).unwrap()
1067 ]
1068 );
1069 }
1070
1071 #[test]
1072 fn test_vectors_ipv6hint_v4mapped() {
1073 use crate::base::net::Ipv6Addr;
1074 use core::str::FromStr;
1075
1076 parse_compose!(
1077 b"\x00\x06\
1078 \x00\x10\
1079 \x00\x00\x00\x00\x00\x00\x00\x00\
1080 \x00\x00\xff\xff\xc6\x33\x64\x64",
1081 [
1082 value::Ipv6Hint::<Octets512>::from_addrs([
1083 Ipv6Addr::from_str("::ffff:198.51.100.100").unwrap(),
1084 ]).unwrap()
1085 ]
1086 );
1087 }
1088
1089 #[cfg(feature = "std")]
1093 #[test]
1094 fn test_representation() {
1095 let mandatory = value::Mandatory::<Octets512>::from_keys(
1096 [
1097 SvcParamKey::ALPN,
1098 SvcParamKey::IPV4HINT,
1099 SvcParamKey::PRIVATE_RANGE_BEGIN.into()
1100 ].into_iter()
1101 ).unwrap();
1102 assert_eq!(
1103 "mandatory=alpn,ipv4hint,key65280",
1104 format!("{}", mandatory)
1105 );
1106
1107 let mut alpn_builder = value::AlpnBuilder::<Octets512>::empty();
1108 alpn_builder.push("h2").unwrap();
1109 alpn_builder.push("h3-19").unwrap();
1110 assert_eq!(
1111 "alpn=h2,h3-19",
1112 format!("{}", alpn_builder.freeze())
1113 );
1114
1115 assert_eq!("nodefaultalpn", format!("{}", value::NoDefaultAlpn));
1116
1117 assert_eq!(
1118 "ech",
1119 format!(
1120 "{}",
1121 value::Ech::from_octets(Octets512::new()).unwrap()
1122 )
1123 );
1124
1125 assert_eq!(
1126 "ipv4hint=192.0.2.1,192.0.2.2",
1127 format!(
1128 "{}",
1129 value::Ipv4Hint::<Octets512>::from_addrs(
1130 [
1131 [192, 0, 2, 1].into(), [192, 0, 2, 2].into()
1132 ]
1133 ).unwrap()
1134 )
1135 );
1136 }
1137
1138
1139 #[test]
1142 fn empty_builder() {
1143 assert_eq!(
1144 Builder512::empty().freeze::<Octets512>().unwrap().as_slice(),
1145 b""
1146 );
1147 }
1148
1149 #[test]
1150 fn one_value() {
1151 let mut builder = Builder512::empty();
1152 builder.push(&value::Port::new(53)).unwrap();
1153 assert_eq!(
1154 builder.freeze::<Octets512>().unwrap().as_slice(),
1155 b"\x00\x03\x00\x02\x00\x35"
1156 );
1157 }
1158
1159 #[test]
1160 fn three_values_in_order() {
1161 let mut builder = Builder512::empty();
1162 builder.push(
1163 &UnknownSvcParam::new(1.into(), b"223").unwrap()
1164 ).unwrap();
1165 builder.push(
1166 &UnknownSvcParam::new(2.into(), b"224").unwrap()
1167 ).unwrap();
1168 builder.push(
1169 &UnknownSvcParam::new(8.into(), b"225").unwrap()
1170 ).unwrap();
1171 assert_eq!(
1172 builder.freeze::<Octets512>().unwrap().as_slice(),
1173 b"\x00\x01\x00\x03223\
1174 \x00\x02\x00\x03224\
1175 \x00\x08\x00\x03225"
1176 );
1177 }
1178
1179 #[test]
1180 fn three_values_out_of_order() {
1181 let mut builder = Builder512::empty();
1182 builder.push(
1183 &UnknownSvcParam::new(1.into(), b"223").unwrap()
1184 ).unwrap();
1185 builder.push(
1186 &UnknownSvcParam::new(8.into(), b"225").unwrap()
1187 ).unwrap();
1188 builder.push(
1189 &UnknownSvcParam::new(2.into(), b"224").unwrap()
1190 ).unwrap();
1191 assert_eq!(
1192 builder.freeze::<Octets512>().unwrap().as_slice(),
1193 b"\x00\x01\x00\x03223\
1194 \x00\x02\x00\x03224\
1195 \x00\x08\x00\x03225"
1196 );
1197 }
1198
1199 #[test]
1200 fn three_values_with_collision() {
1201 let mut builder = Builder512::empty();
1202 builder.push(
1203 &UnknownSvcParam::new(1.into(), b"223").unwrap()
1204 ).unwrap();
1205 builder.push(
1206 &UnknownSvcParam::new(8.into(), b"225").unwrap()
1207 ).unwrap();
1208 assert!(
1209 builder.push(
1210 &UnknownSvcParam::new(8.into(), b"224").unwrap()
1211 ).is_err()
1212 );
1213 }
1214}
1215