base256/
lib.rs

1/*
2 * Copyright (c) 2018, 2023 Erik Nordstrøm <erik@nordstroem.no>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17//! Encode and decode data in base 256
18
19#![forbid(unsafe_code)]
20
21#[cfg(not(any(
22    feature = "encode",
23    feature = "decode",
24    feature = "wl_eff_encode",
25    feature = "wl_pgp_encode"
26)))]
27compile_error!("Building lib target requires that at least one of the following features is enabled: encode; decode; wl_eff_encode; wl_pgp_encode");
28
29#[cfg(any(
30    feature = "decode",
31    feature = "wl_eff_decode",
32    feature = "wl_pgp_decode"
33))]
34mod decode;
35#[cfg(any(
36    feature = "encode",
37    feature = "wl_eff_encode",
38    feature = "wl_pgp_encode"
39))]
40mod encode;
41
42#[cfg(any(
43    feature = "decode",
44    feature = "wl_eff_decode",
45    feature = "wl_pgp_decode"
46))]
47pub use decode::*;
48#[cfg(any(
49    feature = "encode",
50    feature = "wl_eff_encode",
51    feature = "wl_pgp_encode"
52))]
53pub use encode::*;
54
55#[cfg(all(feature = "encode", feature = "decode"))]
56#[cfg(test)]
57mod test_cases_encode {
58    use super::{Decode, Encode};
59    #[cfg(all(feature = "encode_eff", feature = "decode_eff"))]
60    use super::{EffDecode, EffEncode};
61    #[cfg(all(feature = "encode_pgp", feature = "decode_pgp"))]
62    use super::{PgpDecode, PgpEncode};
63    use std::io::{Cursor, Read};
64    use test_case::test_case;
65    use utf8_chars::BufReadCharsExt;
66
67    #[cfg(all(feature = "encode_pgp", feature = "decode_pgp"))]
68    #[test_case(&[0x00u8; 3] ; "data 0x00 0x00 0x00")]
69    #[test_case(&*(0x00u8..=0xFF).collect::<Vec<_>>() ; "data 0x00..0xFF")]
70    #[test_case(&*(0x01u8..=0xFF).collect::<Vec<_>>() ; "data 0x01..0xFF")]
71    fn test_positive_roundtrip_pgp_codec(bytes_orig: &[u8]) {
72        let bytes = Cursor::new(bytes_orig).bytes().into_iter();
73        let encoded_words = Encode::<_, PgpEncode<_>>::encode(bytes)
74            .collect::<Result<String, _>>()
75            .unwrap();
76        let mut cursor = Cursor::new(encoded_words);
77        let words_chars = cursor.chars().into_iter();
78        let decoded_bytes = Decode::<_, PgpDecode<_>>::decode(words_chars)
79            .collect::<Result<Vec<_>, _>>()
80            .unwrap();
81        assert_eq!(bytes_orig, decoded_bytes);
82    }
83
84    #[cfg(all(feature = "encode_eff", feature = "decode_eff"))]
85    #[test_case(&[0x00u8; 3] ; "data 0x00 0x00 0x00")]
86    #[test_case(&*(0x00u8..=0xFF).collect::<Vec<_>>() ; "data 0x00..0xFF")]
87    #[test_case(&*(0x01u8..=0xFF).collect::<Vec<_>>() ; "data 0x01..0xFF")]
88    fn test_positive_roundtrip_eff_codec(bytes_orig: &[u8]) {
89        let bytes = Cursor::new(bytes_orig).bytes().into_iter();
90        let encoded_words = Encode::<_, EffEncode<_>>::encode(bytes)
91            .collect::<Result<String, _>>()
92            .unwrap();
93        let mut cursor = Cursor::new(encoded_words);
94        let words_chars = cursor.chars().into_iter();
95        let decoded_bytes = Decode::<_, EffDecode<_>>::decode(words_chars)
96            .collect::<Result<Vec<_>, _>>()
97            .unwrap();
98        assert_eq!(bytes_orig, decoded_bytes);
99    }
100}