1use std::io::{self, Write};
16use Format;
17
18#[derive(Eq, PartialEq, Copy, Clone, Debug)]
19pub enum C0 {
20 Null,
21 StartHeading,
22 StartText,
23 EndText,
24 EndTransmission,
25 Enquiry,
26 Acknowledge,
27 Bell,
28 Backspace,
29 HorizontalTabulation,
30 LineFeed,
31 VerticalTabulation,
32 FormFeed,
33 CarriageReturn,
34 ShiftOut,
35 ShiftIn,
36 DataLinkEscape,
37 DeviceControlOne,
38 DeviceControlTwo,
39 DeviceControlThree,
40 DeviceControlFour,
41 NegativeAcknowledge,
42 SynchronousIdle,
43 EndTransmissionBlock,
44 Cancel,
45 EndMedium,
46 Substitute,
47 Escape,
48 FileSeparator,
49 GroupSeparator,
50 RecordSeparator,
51 UnitSeparator,
52}
53
54use self::C0::*;
55
56impl Format for C0 {
57 fn fmt<W: Write>(&self, mut f: W) -> io::Result<()> {
58 macro_rules! write {
59 ($code:expr) => (
60 f.write_all(&[$code])
61 );
62 }
63
64 match *self {
65 Null =>
66 write!(0x00),
67
68 StartHeading =>
69 write!(0x01),
70
71 StartText =>
72 write!(0x02),
73
74 EndText =>
75 write!(0x03),
76
77 EndTransmission =>
78 write!(0x04),
79
80 Enquiry =>
81 write!(0x05),
82
83 Acknowledge =>
84 write!(0x06),
85
86 Bell =>
87 write!(0x07),
88
89 Backspace =>
90 write!(0x08),
91
92 HorizontalTabulation =>
93 write!(0x09),
94
95 LineFeed =>
96 write!(0x0A),
97
98 VerticalTabulation =>
99 write!(0x0B),
100
101 FormFeed =>
102 write!(0x0C),
103
104 CarriageReturn =>
105 write!(0x0D),
106
107 ShiftOut =>
108 write!(0x0E),
109
110 ShiftIn =>
111 write!(0x0F),
112
113 DataLinkEscape =>
114 write!(0x10),
115
116 DeviceControlOne =>
117 write!(0x11),
118
119 DeviceControlTwo =>
120 write!(0x12),
121
122 DeviceControlThree =>
123 write!(0x13),
124
125 DeviceControlFour =>
126 write!(0x14),
127
128 NegativeAcknowledge =>
129 write!(0x15),
130
131 SynchronousIdle =>
132 write!(0x16),
133
134 EndTransmissionBlock =>
135 write!(0x17),
136
137 Cancel =>
138 write!(0x18),
139
140 EndMedium =>
141 write!(0x19),
142
143 Substitute =>
144 write!(0x1A),
145
146 Escape =>
147 write!(0x1B),
148
149 FileSeparator =>
150 write!(0x1C),
151
152 GroupSeparator =>
153 write!(0x1D),
154
155 RecordSeparator =>
156 write!(0x1E),
157
158 UnitSeparator =>
159 write!(0x1F),
160 }
161 }
162}
163
164named!(pub parse<C0>,
165 switch!(take!(1),
166 b"\x0D" => call!(CR) |
167 b"\x0A" => call!(LF) |
168 b"\x08" => call!(BS) |
169 b"\x09" => call!(HT) |
170 b"\x1B" => call!(ESC) |
171
172 b"\x00" => call!(NUL) |
173 b"\x01" => call!(SOH) |
174 b"\x02" => call!(STX) |
175 b"\x03" => call!(ETX) |
176 b"\x04" => call!(EOT) |
177 b"\x05" => call!(ENQ) |
178 b"\x06" => call!(ACK) |
179 b"\x07" => call!(BEL) |
180 b"\x0B" => call!(VT) |
181 b"\x0C" => call!(FF) |
182 b"\x0E" => call!(SS) |
183 b"\x0F" => call!(SI) |
184 b"\x10" => call!(DLE) |
185 b"\x11" => call!(DC1) |
186 b"\x12" => call!(DC2) |
187 b"\x13" => call!(DC3) |
188 b"\x14" => call!(DC4) |
189 b"\x15" => call!(NAK) |
190 b"\x16" => call!(SYN) |
191 b"\x17" => call!(ETB) |
192 b"\x18" => call!(CAN) |
193 b"\x19" => call!(EM) |
194 b"\x1A" => call!(SUB) |
195 b"\x1C" => call!(FS) |
196 b"\x1D" => call!(GS) |
197 b"\x1E" => call!(RS) |
198 b"\x1F" => call!(US)));
199
200named!(NUL<C0>,
201 value!(Null));
202
203named!(SOH<C0>,
204 value!(StartHeading));
205
206named!(STX<C0>,
207 value!(StartText));
208
209named!(ETX<C0>,
210 value!(EndText));
211
212named!(EOT<C0>,
213 value!(EndTransmission));
214
215named!(ENQ<C0>,
216 value!(Enquiry));
217
218named!(ACK<C0>,
219 value!(Acknowledge));
220
221named!(BEL<C0>,
222 value!(Bell));
223
224named!(BS<C0>,
225 value!(Backspace));
226
227named!(HT<C0>,
228 value!(HorizontalTabulation));
229
230named!(LF<C0>,
231 value!(LineFeed));
232
233named!(VT<C0>,
234 value!(VerticalTabulation));
235
236named!(FF<C0>,
237 value!(FormFeed));
238
239named!(CR<C0>,
240 value!(CarriageReturn));
241
242named!(SS<C0>,
243 value!(ShiftOut));
244
245named!(SI<C0>,
246 value!(ShiftIn));
247
248named!(DLE<C0>,
249 value!(DataLinkEscape));
250
251named!(DC1<C0>,
252 value!(DeviceControlOne));
253
254named!(DC2<C0>,
255 value!(DeviceControlTwo));
256
257named!(DC3<C0>,
258 value!(DeviceControlThree));
259
260named!(DC4<C0>,
261 value!(DeviceControlFour));
262
263named!(NAK<C0>,
264 value!(NegativeAcknowledge));
265
266named!(SYN<C0>,
267 value!(SynchronousIdle));
268
269named!(ETB<C0>,
270 value!(EndTransmissionBlock));
271
272named!(CAN<C0>,
273 value!(Cancel));
274
275named!(EM<C0>,
276 value!(EndMedium));
277
278named!(SUB<C0>,
279 value!(Substitute));
280
281named!(ESC<C0>,
282 value!(Escape));
283
284named!(FS<C0>,
285 value!(FileSeparator));
286
287named!(GS<C0>,
288 value!(GroupSeparator));
289
290named!(RS<C0>,
291 value!(RecordSeparator));
292
293named!(US<C0>,
294 value!(UnitSeparator));
295
296pub mod shim {
297 pub use super::C0 as T;
298 pub use super::C0::*;
299 pub use super::parse;
300}
301
302#[cfg(test)]
303mod test {
304 mod parse {
305 use {Control, C0, parse};
306
307 macro_rules! test {
308 ($id:expr => $attr:expr) => (
309 assert_eq!(Control::C0($attr),
310 parse(&[$id]).unwrap().1);
311 );
312 }
313
314 #[test]
315 fn nul() {
316 test!(0x00 =>
317 C0::Null);
318 }
319
320 #[test]
321 fn soh() {
322 test!(0x01 =>
323 C0::StartHeading);
324 }
325
326 #[test]
327 fn stx() {
328 test!(0x02 =>
329 C0::StartText);
330 }
331
332 #[test]
333 fn etx() {
334 test!(0x03 =>
335 C0::EndText);
336 }
337
338 #[test]
339 fn eot() {
340 test!(0x04 =>
341 C0::EndTransmission);
342 }
343
344 #[test]
345 fn enq() {
346 test!(0x05 =>
347 C0::Enquiry);
348 }
349
350 #[test]
351 fn ack() {
352 test!(0x06 =>
353 C0::Acknowledge);
354 }
355
356 #[test]
357 fn bel() {
358 test!(0x07 =>
359 C0::Bell);
360 }
361
362 #[test]
363 fn bs() {
364 test!(0x08 =>
365 C0::Backspace);
366 }
367
368 #[test]
369 fn ht() {
370 test!(0x09 =>
371 C0::HorizontalTabulation);
372 }
373
374 #[test]
375 fn lf() {
376 test!(0x0A =>
377 C0::LineFeed);
378 }
379
380 #[test]
381 fn vf() {
382 test!(0x0B =>
383 C0::VerticalTabulation);
384 }
385
386 #[test]
387 fn ff() {
388 test!(0x0C =>
389 C0::FormFeed);
390 }
391
392 #[test]
393 fn cr() {
394 test!(0x0D =>
395 C0::CarriageReturn);
396 }
397
398 #[test]
399 fn ss() {
400 test!(0x0E =>
401 C0::ShiftOut);
402 }
403
404 #[test]
405 fn si() {
406 test!(0x0F =>
407 C0::ShiftIn);
408 }
409
410 #[test]
411 fn dle() {
412 test!(0x10 =>
413 C0::DataLinkEscape);
414 }
415
416 #[test]
417 fn dc1() {
418 test!(0x11 =>
419 C0::DeviceControlOne);
420 }
421
422 #[test]
423 fn dc2() {
424 test!(0x12 =>
425 C0::DeviceControlTwo);
426 }
427
428 #[test]
429 fn dc3() {
430 test!(0x13 =>
431 C0::DeviceControlThree);
432 }
433
434 #[test]
435 fn dc4() {
436 test!(0x14 =>
437 C0::DeviceControlFour);
438 }
439
440 #[test]
441 fn nak() {
442 test!(0x15 =>
443 C0::NegativeAcknowledge);
444 }
445
446 #[test]
447 fn syn() {
448 test!(0x16 =>
449 C0::SynchronousIdle);
450 }
451
452 #[test]
453 fn etb() {
454 test!(0x17 =>
455 C0::EndTransmissionBlock);
456 }
457
458 #[test]
459 fn can() {
460 test!(0x18 =>
461 C0::Cancel);
462 }
463
464 #[test]
465 fn em() {
466 test!(0x19 =>
467 C0::EndMedium);
468 }
469
470 #[test]
471 fn sub() {
472 test!(0x1A =>
473 C0::Substitute);
474 }
475
476 #[test]
477 fn fs() {
478 test!(0x1C =>
479 C0::FileSeparator);
480 }
481
482 #[test]
483 fn gs() {
484 test!(0x1D =>
485 C0::GroupSeparator);
486 }
487
488 #[test]
489 fn rs() {
490 test!(0x1E =>
491 C0::RecordSeparator);
492 }
493
494 #[test]
495 fn us() {
496 test!(0x1F =>
497 C0::UnitSeparator);
498 }
499 }
500
501 mod format {
502 use {Control, C0, format, parse};
503
504 macro_rules! test {
505 ($code:expr) => (
506 let item = Control::C0($code);
507 assert_eq!(item, parse(&format(&item)).unwrap().1);
508 );
509 }
510
511 #[test]
512 fn nul() {
513 test!(C0::Null);
514 }
515
516 #[test]
517 fn soh() {
518 test!(C0::StartHeading);
519 }
520
521 #[test]
522 fn stx() {
523 test!(C0::StartText);
524 }
525
526 #[test]
527 fn etx() {
528 test!(C0::EndText);
529 }
530
531 #[test]
532 fn eot() {
533 test!(C0::EndTransmission);
534 }
535
536 #[test]
537 fn enq() {
538 test!(C0::Enquiry);
539 }
540
541 #[test]
542 fn ack() {
543 test!(C0::Acknowledge);
544 }
545
546 #[test]
547 fn bel() {
548 test!(C0::Bell);
549 }
550
551 #[test]
552 fn bs() {
553 test!(C0::Backspace);
554 }
555
556 #[test]
557 fn ht() {
558 test!(C0::HorizontalTabulation);
559 }
560
561 #[test]
562 fn lf() {
563 test!(C0::LineFeed);
564 }
565
566 #[test]
567 fn vf() {
568 test!(C0::VerticalTabulation);
569 }
570
571 #[test]
572 fn ff() {
573 test!(C0::FormFeed);
574 }
575
576 #[test]
577 fn cr() {
578 test!(C0::CarriageReturn);
579 }
580
581 #[test]
582 fn ss() {
583 test!(C0::ShiftOut);
584 }
585
586 #[test]
587 fn si() {
588 test!(C0::ShiftIn);
589 }
590
591 #[test]
592 fn dle() {
593 test!(C0::DataLinkEscape);
594 }
595
596 #[test]
597 fn dc1() {
598 test!(C0::DeviceControlOne);
599 }
600
601 #[test]
602 fn dc2() {
603 test!(C0::DeviceControlTwo);
604 }
605
606 #[test]
607 fn dc3() {
608 test!(C0::DeviceControlThree);
609 }
610
611 #[test]
612 fn dc4() {
613 test!(C0::DeviceControlFour);
614 }
615
616 #[test]
617 fn nak() {
618 test!(C0::NegativeAcknowledge);
619 }
620
621 #[test]
622 fn syn() {
623 test!(C0::SynchronousIdle);
624 }
625
626 #[test]
627 fn etb() {
628 test!(C0::EndTransmissionBlock);
629 }
630
631 #[test]
632 fn can() {
633 test!(C0::Cancel);
634 }
635
636 #[test]
637 fn em() {
638 test!(C0::EndMedium);
639 }
640
641 #[test]
642 fn sub() {
643 test!(C0::Substitute);
644 }
645
646 #[test]
647 fn fs() {
648 test!(C0::FileSeparator);
649 }
650
651 #[test]
652 fn gs() {
653 test!(C0::GroupSeparator);
654 }
655
656 #[test]
657 fn rs() {
658 test!(C0::RecordSeparator);
659 }
660
661 #[test]
662 fn us() {
663 test!(C0::UnitSeparator);
664 }
665 }
666}