hickory_proto/op/lower_query.rs
1// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use core::fmt::{self, Display};
9
10use crate::error::*;
11use crate::op::Query;
12use crate::rr::LowerName;
13use crate::rr::{DNSClass, RecordType};
14use crate::serialize::binary::*;
15
16/// Identical to [`Query`], except that the Name is guaranteed to be in lower case form.
17///
18/// This guarantee is helpful for performance reasons, as case-sensitive comparisons
19/// can be done faster. Name comparison is a frequent operation and so overall performance
20/// benefits.
21#[derive(Clone, Debug, PartialEq, Eq)]
22pub struct LowerQuery {
23 name: LowerName,
24 original: Query,
25}
26
27impl LowerQuery {
28 /// Create a new query from name and type, class defaults to IN
29 pub fn query(query: Query) -> Self {
30 Self {
31 name: LowerName::new(query.name()),
32 original: query,
33 }
34 }
35
36 /// ```text
37 /// QNAME a domain name represented as a sequence of labels, where
38 /// each label consists of a length octet followed by that
39 /// number of octets. The domain name terminates with the
40 /// zero length octet for the null label of the root. Note
41 /// that this field may be an odd number of octets; no
42 /// padding is used.
43 /// ```
44 pub fn name(&self) -> &LowerName {
45 &self.name
46 }
47
48 /// Returns the original with the `Name`s case preserved
49 pub fn original(&self) -> &Query {
50 &self.original
51 }
52
53 /// ```text
54 /// QTYPE a two octet code which specifies the type of the query.
55 /// The values for this field include all codes valid for a
56 /// TYPE field, together with some more general codes which
57 /// can match more than one type of RR.
58 /// ```
59 pub fn query_type(&self) -> RecordType {
60 self.original.query_type()
61 }
62
63 /// ```text
64 /// QCLASS a two octet code that specifies the class of the query.
65 /// For example, the QCLASS field is IN for the Internet.
66 /// ```
67 pub fn query_class(&self) -> DNSClass {
68 self.original.query_class()
69 }
70}
71
72impl From<Query> for LowerQuery {
73 fn from(query: Query) -> Self {
74 Self::query(query)
75 }
76}
77
78impl BinEncodable for LowerQuery {
79 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
80 self.original.emit(encoder)
81 }
82}
83
84impl<'r> BinDecodable<'r> for LowerQuery {
85 fn read(decoder: &mut BinDecoder<'r>) -> Result<Self, DecodeError> {
86 let original = Query::read(decoder)?;
87 Ok(Self::query(original))
88 }
89}
90
91impl Display for LowerQuery {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
93 write!(
94 f,
95 "name: {} type: {} class: {}",
96 self.name,
97 self.original.query_type(),
98 self.original.query_class()
99 )
100 }
101}