1use std::{fmt, iter};
7use bytes::BufMut;
8use ::bits::compose::{Compose, Compress, Compressor};
9use ::bits::parse::ShortBuf;
10use super::label::Label;
11use super::relative::DnameIter;
12use super::traits::{ToLabelIter, ToRelativeDname, ToDname};
13use super::uncertain::UncertainDname;
14
15
16#[derive(Clone, Debug)]
36pub struct Chain<L, R> {
37 left: L,
39
40 right: R,
42}
43
44impl<L: Compose, R: Compose> Chain<L, R> {
45 pub(super) fn new(left: L, right: R) -> Result<Self, LongChainError> {
47 if left.compose_len() + right.compose_len() > 255 {
48 Err(LongChainError)
49 }
50 else {
51 Ok(Chain { left, right })
52 }
53 }
54}
55
56impl<R: Compose> Chain<UncertainDname, R> {
57 pub(super) fn new_uncertain(left: UncertainDname, right: R)
62 -> Result<Self, LongChainError> {
63 if let UncertainDname::Relative(ref name) = left {
64 if name.compose_len() + right.compose_len() > 255 {
65 return Err(LongChainError)
66 }
67 }
68 Ok(Chain { left, right })
69 }
70}
71
72impl<L: ToRelativeDname, R: Compose> Chain<L, R> {
73 pub fn chain<N: Compose>(self, other: N)
87 -> Result<Chain<Self, N>, LongChainError> {
88 Chain::new(self, other)
89 }
90}
91
92impl<L, R> Chain<L, R> {
93 pub fn unwrap(self) -> (L, R) {
95 (self.left, self.right)
96 }
97}
98
99impl<'a, L: ToRelativeDname, R: for<'r> ToLabelIter<'r>> ToLabelIter<'a>
100 for Chain<L, R> {
101 type LabelIter = ChainIter<'a, L, R>;
102
103 fn iter_labels(&'a self) -> Self::LabelIter {
104 ChainIter(self.left.iter_labels().chain(self.right.iter_labels()))
105 }
106}
107
108impl<L: ToRelativeDname, R: Compose> Compose for Chain<L, R> {
109 fn compose_len(&self) -> usize {
110 self.left.compose_len() + self.right.compose_len()
111 }
112
113 fn compose<B: BufMut>(&self, buf: &mut B) {
114 self.left.compose(buf);
115 self.right.compose(buf)
116 }
117}
118
119impl<L: ToRelativeDname, R: ToDname> Compress for Chain<L, R> {
120 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
121 buf.compress_name(self)
122 }
123}
124
125impl<L: ToRelativeDname, R: ToRelativeDname> ToRelativeDname for Chain<L, R> {
126}
127
128impl<L: ToRelativeDname, R: ToDname> ToDname for Chain<L, R> {
129}
130
131impl<L: fmt::Display, R: fmt::Display> fmt::Display for Chain<L, R> {
132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133 write!(f, "{}.{}", self.left, self.right)
134 }
135}
136
137impl<'a, R: ToDname> ToLabelIter<'a> for Chain<UncertainDname, R> {
138 type LabelIter = UncertainChainIter<'a, R>;
139
140 fn iter_labels(&'a self) -> Self::LabelIter {
141 match self.left {
142 UncertainDname::Absolute(ref name) => {
143 UncertainChainIter::Absolute(name.iter_labels())
144 }
145 UncertainDname::Relative(ref name) => {
146 UncertainChainIter::Relative(
147 ChainIter(name.iter_labels()
148 .chain(self.right.iter_labels()))
149 )
150 }
151 }
152 }
153}
154
155impl<R: ToDname> Compose for Chain<UncertainDname, R> {
156 fn compose_len(&self) -> usize {
157 match self.left {
158 UncertainDname::Absolute(ref name) => name.compose_len(),
159 UncertainDname::Relative(ref name) => {
160 name.compose_len() + self.right.compose_len()
161 }
162 }
163 }
164
165 fn compose<B: BufMut>(&self, buf: &mut B) {
166 match self.left {
167 UncertainDname::Absolute(ref name) => name.compose(buf),
168 UncertainDname::Relative(ref name) => {
169 name.compose(buf);
170 self.right.compose(buf)
171 }
172 }
173 }
174}
175
176
177impl<R: ToDname> Compress for Chain<UncertainDname, R> {
178 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
179 if let UncertainDname::Absolute(ref name) = self.left {
180 buf.compress_name(name)
181 }
182 else {
183 buf.compress_name(self)
185 }
186 }
187}
188
189impl<R: ToDname> ToDname for Chain<UncertainDname, R> { }
190
191
192#[derive(Clone, Debug)]
196pub struct ChainIter<'a, L: ToLabelIter<'a>, R: ToLabelIter<'a>>(
197 iter::Chain<L::LabelIter, R::LabelIter>
198);
199
200impl<'a, L, R> Iterator for ChainIter<'a, L, R>
201 where L: ToLabelIter<'a>, R: ToLabelIter<'a> {
202 type Item = &'a Label;
203
204 fn next(&mut self) -> Option<Self::Item> {
205 self.0.next()
206 }
207}
208
209impl<'a, L, R> DoubleEndedIterator for ChainIter<'a, L, R>
210 where L: ToLabelIter<'a>, R: ToLabelIter<'a> {
211 fn next_back(&mut self) -> Option<Self::Item> {
212 self.0.next_back()
213 }
214}
215
216
217pub enum UncertainChainIter<'a, R: ToLabelIter<'a>> {
221 Absolute(DnameIter<'a>),
222 Relative(ChainIter<'a, UncertainDname, R>),
223}
224
225impl<'a, R> Iterator for UncertainChainIter<'a, R>
226where R: ToLabelIter<'a>
227{
228 type Item = &'a Label;
229
230 fn next(&mut self) -> Option<Self::Item> {
231 match *self {
232 UncertainChainIter::Absolute(ref mut inner) => inner.next(),
233 UncertainChainIter::Relative(ref mut inner) => inner.next()
234 }
235 }
236}
237
238impl<'a, R> DoubleEndedIterator for UncertainChainIter<'a, R>
239where R: ToLabelIter<'a>
240{
241 fn next_back(&mut self) -> Option<Self::Item> {
242 match *self {
243 UncertainChainIter::Absolute(ref mut inner) => inner.next_back(),
244 UncertainChainIter::Relative(ref mut inner) => inner.next_back()
245 }
246 }
247}
248
249
250#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
254#[fail(display="long domain name")]
255pub struct LongChainError;
256
257
258#[cfg(test)]
261mod test {
262 use bytes::BytesMut;
263 use ::bits::compose::{Compose, Compress, Compressor};
264 use ::bits::name::{Dname, DnameBuilder, Label, RelativeDname, ToDname,
265 ToLabelIter, ToRelativeDname, UncertainDname};
266
267 fn assert_to_dname<T: ToDname>(_: &T) { }
268 fn assert_to_relative_dname<T: ToRelativeDname>(_: &T) { }
269
270 #[test]
273 fn impls() {
274 let rel = RelativeDname::empty()
275 .chain(RelativeDname::empty()).unwrap();
276 assert_to_dname(&RelativeDname::empty().chain(Dname::root()).unwrap());
277 assert_to_relative_dname(&rel);
278 assert_to_dname(&rel.clone().chain(Dname::root()).unwrap());
279 assert_to_relative_dname(&rel.chain(RelativeDname::empty()).unwrap());
280 assert_to_dname(&UncertainDname::root().chain(Dname::root()).unwrap());
281 }
282
283 #[test]
285 fn name_limit() {
286 let mut builder = DnameBuilder::new();
287 for _ in 0..25 {
288 builder.append_label(b"123456789").unwrap();
290 }
291 let left = builder.finish();
292 assert_eq!(left.len(), 250);
293
294 let mut builder = DnameBuilder::new();
295 builder.append(b"123").unwrap();
296 let five_abs = builder.clone().into_dname().unwrap();
297 assert_eq!(five_abs.len(), 5);
298 builder.push(b'4').unwrap();
299 let five_rel = builder.clone().finish();
300 assert_eq!(five_rel.len(), 5);
301 let six_abs = builder.clone().into_dname().unwrap();
302 assert_eq!(six_abs.len(), 6);
303 builder.push(b'5').unwrap();
304 let six_rel = builder.finish();
305 assert_eq!(six_rel.len(), 6);
306
307 assert_eq!(left.clone().chain(five_abs.clone())
308 .unwrap().compose_len(),
309 255);
310 assert_eq!(left.clone().chain(five_rel.clone())
311 .unwrap().compose_len(),
312 255);
313 assert!(left.clone().chain(six_abs.clone()).is_err());
314 assert!(left.clone().chain(six_rel.clone()).is_err());
315 assert!(left.clone().chain(five_rel.clone()).unwrap()
316 .chain(five_abs.clone()).is_err());
317 assert!(left.clone().chain(five_rel.clone()).unwrap()
318 .chain(five_rel.clone()).is_err());
319
320 let left = UncertainDname::from(left);
321 assert_eq!(left.clone().chain(five_abs.clone())
322 .unwrap().compose_len(),
323 255);
324 assert!(left.clone().chain(six_abs.clone()).is_err());
325
326 let left = UncertainDname::from(left.into_absolute());
327 assert_eq!(left.clone().chain(six_abs.clone())
328 .unwrap().compose_len(),
329 251);
330 }
331
332 fn cmp_iter<'a, I>(iter: I, labels: &[&[u8]])
333 where I: Iterator<Item=&'a Label> {
334 let labels = labels.iter().map(|s| Label::from_slice(s).unwrap());
335 assert!(iter.eq(labels))
336 }
337
338 #[test]
340 fn iter_labels() {
341 let w = RelativeDname::from_slice(b"\x03www").unwrap();
342 let ec = RelativeDname::from_slice(b"\x07example\x03com").unwrap();
343 let ecr = Dname::from_slice(b"\x07example\x03com\x00").unwrap();
344 let fbr = Dname::from_slice(b"\x03foo\x03bar\x00").unwrap();
345
346 cmp_iter(w.clone().chain(ec.clone()).unwrap().iter_labels(),
347 &[b"www", b"example", b"com"]);
348 cmp_iter(w.clone().chain(ecr.clone()).unwrap().iter_labels(),
349 &[b"www", b"example", b"com", b""]);
350 cmp_iter(w.clone().chain(ec.clone()).unwrap()
351 .chain(Dname::root()).unwrap().iter_labels(),
352 &[b"www", b"example", b"com", b""]);
353
354 cmp_iter(UncertainDname::from(w.clone())
355 .chain(ecr.clone()).unwrap().iter_labels(),
356 &[b"www", b"example", b"com", b""]);
357 cmp_iter(UncertainDname::from(ecr.clone())
358 .chain(fbr.clone()).unwrap().iter_labels(),
359 &[b"example", b"com", b""]);
360 }
361
362 #[test]
364 fn compose() {
365 let w = RelativeDname::from_slice(b"\x03www").unwrap();
366 let ec = RelativeDname::from_slice(b"\x07example\x03com").unwrap();
367 let ecr = Dname::from_slice(b"\x07example\x03com\x00").unwrap();
368 let fbr = Dname::from_slice(b"\x03foo\x03bar\x00").unwrap();
369
370 let mut buf = BytesMut::with_capacity(255);
371 w.clone().chain(ec.clone()).unwrap().compose(&mut buf);
372 assert_eq!(buf.freeze().as_ref(),
373 b"\x03www\x07example\x03com");
374
375 let mut buf = BytesMut::with_capacity(255);
376 w.clone().chain(ecr.clone()).unwrap().compose(&mut buf);
377 assert_eq!(buf.freeze().as_ref(),
378 b"\x03www\x07example\x03com\x00");
379
380 let mut buf = BytesMut::with_capacity(255);
381 w.clone().chain(ec.clone()).unwrap().chain(Dname::root()).unwrap()
382 .compose(&mut buf);
383 assert_eq!(buf.freeze().as_ref(),
384 b"\x03www\x07example\x03com\x00");
385
386 let mut buf = BytesMut::with_capacity(255);
387 UncertainDname::from(w.clone()).chain(ecr.clone()).unwrap()
388 .compose(&mut buf);
389 assert_eq!(buf.freeze().as_ref(),
390 b"\x03www\x07example\x03com\x00");
391
392 let mut buf = BytesMut::with_capacity(255);
393 UncertainDname::from(ecr.clone()).chain(fbr.clone()).unwrap()
394 .compose(&mut buf);
395 assert_eq!(buf.freeze().as_ref(),
396 b"\x07example\x03com\x00");
397 }
398
399 #[test]
401 fn compress() {
402 let w = RelativeDname::from_slice(b"\x03www").unwrap();
403 let ec = RelativeDname::from_slice(b"\x07example\x03com").unwrap();
404 let ecr = Dname::from_slice(b"\x07example\x03com\x00").unwrap();
405 let fbr = Dname::from_slice(b"\x03foo\x03bar\x00").unwrap();
406
407 let mut buf = Compressor::with_capacity(255);
408 w.clone().chain(ecr.clone()).unwrap().compress(&mut buf).unwrap();
409 assert_eq!(buf.freeze().as_ref(),
410 b"\x03www\x07example\x03com\x00");
411
412 let mut buf = Compressor::with_capacity(255);
413 w.clone().chain(ec.clone()).unwrap().chain(Dname::root()).unwrap()
414 .compress(&mut buf).unwrap();
415 assert_eq!(buf.freeze().as_ref(),
416 b"\x03www\x07example\x03com\x00");
417
418 let mut buf = Compressor::with_capacity(255);
419 UncertainDname::from(w.clone()).chain(ecr.clone()).unwrap()
420 .compress(&mut buf).unwrap();
421 assert_eq!(buf.freeze().as_ref(),
422 b"\x03www\x07example\x03com\x00");
423
424 let mut buf = Compressor::with_capacity(255);
425 UncertainDname::from(ecr.clone()).chain(fbr.clone()).unwrap()
426 .compress(&mut buf).unwrap();
427 assert_eq!(buf.freeze().as_ref(),
428 b"\x07example\x03com\x00");
429 }
430}