ansi_color_codec/
codec.rs

1use core::iter::FlatMap;
2
3use crate::Error;
4use crate::code_pair::CodePair;
5use crate::pair_decoder::PairDecoder;
6use crate::parser::Parser;
7
8/// Gives the ability to en- / decode bytes to / from ANSI background colors.
9pub trait Codec: Encoder + Decoder + Sized {
10    /// Encode bytes into ANSI colors.
11    fn encode(self) -> <Self as Encoder>::Encoder {
12        <Self as Encoder>::encode(self)
13    }
14
15    /// Decode ANSI color codes into bytes.
16    fn decode(self) -> <Self as Decoder>::Decoder {
17        <Self as Decoder>::decode(self)
18    }
19}
20
21/// Gives the ability to encode bytes to ANSI background colors.
22pub trait Encoder {
23    /// Type to encode bytes into ANSI color codes.
24    type Encoder;
25    /// Error type.
26    type Error;
27
28    /// Encode bytes into ANSI colors.
29    fn encode(self) -> Self::Encoder;
30}
31
32/// Gives the ability to decode bytes from ANSI background colors.
33pub trait Decoder {
34    /// A type to parse color codes.
35    type Parser;
36    /// A type to decode color codes.
37    type Decoder;
38    /// Error type.
39    type Error;
40
41    /// Parse bytes into color codes.
42    fn parse(self) -> Self::Parser;
43
44    /// Decode color codes to bytes.
45    fn decode(self) -> Self::Decoder;
46}
47
48impl<T> Encoder for T
49where
50    T: Iterator<Item = u8>,
51{
52    type Encoder = FlatMap<T, CodePair, fn(u8) -> CodePair>;
53    type Error = Error;
54
55    /// Return an iterator that encodes all bytes as ANSI background colors.
56    ///
57    /// # Examples
58    ///
59    /// ```
60    /// use ansi_color_codec::Codec;
61    ///
62    /// let text = String::from("Hello world.");
63    /// let reference: Vec<u8> = vec![
64    ///     27, 91, 52, 52, 109, 32, 27, 91, 49, 48, 48, 109, 32, 27, 91, 52, 54, 109, 32, 27, 91,
65    ///     52, 53, 109, 32, 27, 91, 52, 54, 109, 32, 27, 91, 49, 48, 52, 109, 32, 27, 91, 52, 54,
66    ///     109, 32, 27, 91, 49, 48, 52, 109, 32, 27, 91, 52, 54, 109, 32, 27, 91, 49, 48, 55, 109,
67    ///     32, 27, 91, 52, 50, 109, 32, 27, 91, 52, 48, 109, 32, 27, 91, 52, 55, 109, 32, 27, 91,
68    ///     52, 55, 109, 32, 27, 91, 52, 54, 109, 32, 27, 91, 49, 48, 55, 109, 32, 27, 91, 52, 55,
69    ///     109, 32, 27, 91, 52, 50, 109, 32, 27, 91, 52, 54, 109, 32, 27, 91, 49, 48, 52, 109, 32,
70    ///     27, 91, 52, 54, 109, 32, 27, 91, 52, 52, 109, 32, 27, 91, 52, 50, 109, 32, 27, 91, 49,
71    ///     48, 54, 109, 32,
72    /// ];
73    /// let code: Vec<u8> = text
74    ///     .bytes()
75    ///     .encode()
76    ///     .flat_map(|color| color.to_string().into_bytes())
77    ///     .collect();
78    /// assert_eq!(code, reference);
79    /// ```
80    fn encode(self) -> Self::Encoder {
81        self.flat_map(CodePair::from)
82    }
83}
84
85impl<T> Decoder for T {
86    type Parser = Parser<T>;
87    type Decoder = PairDecoder<Parser<T>>;
88    type Error = Error;
89
90    /// Parse ANSI color codes from a byte iterator.
91    fn parse(self) -> Self::Parser {
92        self.into()
93    }
94
95    /// Return an iterator that decodes all bytes interpreted as a sequence of ANSI background
96    /// colors to raw bytes.
97    ///
98    /// # Examples
99    ///
100    /// ```
101    /// use ansi_color_codec::Codec;
102    ///
103    /// let text = String::from("Hello world.");
104    /// let code: String = text
105    ///     .bytes()
106    ///     .encode()
107    ///     .map(|color| color.to_string())
108    ///     .collect();
109    /// let decoded: String = code
110    ///     .bytes()
111    ///     .decode()
112    ///     .filter_map(|result| result.map(|byte| byte as char).ok())
113    ///     .collect();
114    /// assert_eq!(text, decoded);
115    /// ```
116    fn decode(self) -> Self::Decoder {
117        <Self as Decoder>::parse(self).into()
118    }
119}
120
121impl<T> Codec for T where T: Encoder + Decoder + Sized {}