control_code/
c0.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15use 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}