From e132e4695d182eae5879c9c32de9f86fc3b93222 Mon Sep 17 00:00:00 2001 From: Brian Faga Date: Fri, 21 Jul 2023 21:49:05 -0400 Subject: [PATCH 1/3] add line_wrap to encoding config --- src/lib.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3c240c1..d20f5ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -144,7 +144,10 @@ pub enum LineEnding { #[derive(Debug, Clone, Copy)] pub struct EncodeConfig { /// Line ending to use during encoding - pub line_ending: LineEnding, + line_ending: LineEnding, + + /// Line length to use during encoding + line_wrap: usize, } /// A representation of Pem-encoded data @@ -234,6 +237,34 @@ impl HeaderMap { } } +impl EncodeConfig { + /// Create a new encode config with default values. + pub fn new() -> Self { + Self::default() + } + + /// Set the line ending to use for the encoding. + pub fn set_line_ending(mut self, line_ending: LineEnding) -> Self { + self.line_ending = line_ending; + self + } + + /// Set the line length to use for the encoding. + pub fn set_line_wrap(mut self, line_wrap: usize) -> Self { + self.line_wrap = line_wrap; + self + } +} + +impl Default for EncodeConfig { + fn default() -> Self { + Self { + line_ending: LineEnding::CRLF, + line_wrap: LINE_WRAP, + } + } +} + impl Pem { /// Create a new Pem struct pub fn new(tag: impl ToString, contents: impl Into>) -> Pem { @@ -461,12 +492,7 @@ pub fn parse_many>(input: B) -> Result> { /// encode(&pem); /// ``` pub fn encode(pem: &Pem) -> String { - encode_config( - pem, - EncodeConfig { - line_ending: LineEnding::CRLF, - }, - ) + encode_config(pem, EncodeConfig::default()) } /// Encode a PEM struct into a PEM-encoded data string with additional @@ -500,7 +526,7 @@ pub fn encode_config(pem: &Pem, config: EncodeConfig) -> String { } output.push_str(line_ending); } - for c in contents.as_bytes().chunks(LINE_WRAP) { + for c in contents.as_bytes().chunks(config.line_wrap) { output.push_str(&format!("{}{}", str::from_utf8(c).unwrap(), line_ending)); } output.push_str(&format!("-----END {}-----{}", pem.tag, line_ending)); @@ -644,6 +670,17 @@ ijoUXIDruJQEGFGvZTsi1D2RehXiT90CIQC4HOQUYKCydB7oWi1SHDokFW2yFyo6 /+lf3fgNjPI6OQIgUPmTFXciXxT1msh3gFLf3qt2Kv8wbr9Ad9SXjULVpGkCIB+g RzHX0lkJl9Stshd/7Gbt65/QYq+v+xvAeT0CoyIg -----END RSA PUBLIC KEY----- +"; + + const SAMPLE_DEFAULT_LINE_WRAP: &str = "-----BEGIN TEST-----\r +AQIDBA==\r +-----END TEST-----\r +"; + + const SAMPLE_CUSTOM_LINE_WRAP_4: &str = "-----BEGIN TEST-----\r +AQID\r +BA==\r +-----END TEST-----\r "; #[test] @@ -731,6 +768,20 @@ RzHX0lkJl9Stshd/7Gbt65/QYq+v+xvAeT0CoyIg assert_eq!(parse_many(input), Err(PemError::MissingBeginTag)); } + #[test] + fn test_encode_default_line_wrap() { + let pem = Pem::new("TEST", vec![1, 2, 3, 4]); + assert_eq!(encode(&pem), SAMPLE_DEFAULT_LINE_WRAP); + } + + #[test] + fn test_encode_custom_line_wrap_4() { + let pem = Pem::new("TEST", vec![1, 2, 3, 4]); + assert_eq!( + encode_config(&pem, EncodeConfig::default().set_line_wrap(4)), + SAMPLE_CUSTOM_LINE_WRAP_4 + ); + } #[test] fn test_encode_empty_contents() { let pem = Pem::new("FOO", vec![]); @@ -762,9 +813,7 @@ RzHX0lkJl9Stshd/7Gbt65/QYq+v+xvAeT0CoyIg #[test] fn test_encode_config_contents() { let pem = Pem::new("FOO", [1, 2, 3, 4]); - let config = EncodeConfig { - line_ending: LineEnding::LF, - }; + let config = EncodeConfig::default().set_line_ending(LineEnding::LF); let encoded = encode_config(&pem, config); assert!(!encoded.is_empty()); @@ -775,9 +824,7 @@ RzHX0lkJl9Stshd/7Gbt65/QYq+v+xvAeT0CoyIg #[test] fn test_encode_many_config() { let pems = parse_many(SAMPLE_LF).unwrap(); - let config = EncodeConfig { - line_ending: LineEnding::LF, - }; + let config = EncodeConfig::default().set_line_ending(LineEnding::LF); let encoded = encode_many_config(&pems, config); assert_eq!(SAMPLE_LF, encoded); From ba4962fda16c8ef0a43d85c944c98f7579f2bfaa Mon Sep 17 00:00:00 2001 From: Brian Faga Date: Mon, 24 Jul 2023 19:49:33 -0400 Subject: [PATCH 2/3] update changelog for line_wrap option --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 476fb6d..7df62fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased - trim `proptest` features to prevent an MSRV break for testing + - make EncodeConfig struct extendable and add a line_wrap config option # 2.0.1 From 7e1f40b74176ecc9a76921ce0139cc58ee2ae83b Mon Sep 17 00:00:00 2001 From: Brian Faga Date: Mon, 24 Jul 2023 20:11:40 -0400 Subject: [PATCH 3/3] fix doc tests --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d20f5ec..062c7b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -503,7 +503,7 @@ pub fn encode(pem: &Pem) -> String { /// use pem::{Pem, encode_config, EncodeConfig, LineEnding}; /// /// let pem = Pem::new("FOO", [1, 2, 3, 4]); -/// encode_config(&pem, EncodeConfig { line_ending: LineEnding::LF }); +/// encode_config(&pem, EncodeConfig::new().set_line_ending(LineEnding::LF)); /// ``` pub fn encode_config(pem: &Pem, config: EncodeConfig) -> String { let line_ending = match config.line_ending { @@ -566,7 +566,7 @@ pub fn encode_many(pems: &[Pem]) -> String { /// Pem::new("FOO", [1, 2, 3, 4]), /// Pem::new("BAR", [5, 6, 7, 8]), /// ]; -/// encode_many_config(&data, EncodeConfig { line_ending: LineEnding::LF }); +/// encode_many_config(&data, EncodeConfig::new().set_line_ending(LineEnding::LF)); /// ``` pub fn encode_many_config(pems: &[Pem], config: EncodeConfig) -> String { let line_ending = match config.line_ending {