Skip to content

Commit

Permalink
Merge pull request #34 from tmpfs/serde-feature
Browse files Browse the repository at this point in the history
Support optional serde feature
  • Loading branch information
jcreekmore committed Jul 13, 2022
2 parents 2ebf2b1 + 6381ef4 commit 0b37bd8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ rust-version = "1.34.2"

[dependencies]
base64 = "0.13.0"
serde = { version = "1", optional = true, features = ["serde_derive"] }

[dev-dependencies]
criterion = "0.3.0"
serde_json = "1"

[[bench]]
name = "pem_benchmark"
Expand Down
62 changes: 61 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//!
//! ```toml
//! [dependencies]
//! pem = "0.8"
//! pem = "1"
//! ```
//!
//! and this to your crate root:
Expand All @@ -28,6 +28,9 @@
//! extern crate pem;
//! ```
//!
//! Using the `serde` feature will implement the serde traits for
//! the `Pem` struct.
//!
//! # Example: parse a single chunk of PEM-encoded text
//!
//! Generally, PEM-encoded files contain a single chunk of PEM-encoded
Expand Down Expand Up @@ -421,6 +424,51 @@ pub fn encode_many_config(pems: &[Pem], config: EncodeConfig) -> String {
.join(line_ending)
}

#[cfg(feature = "serde")]
mod serde_impl {
use super::{encode, parse, Pem};
use serde::{
de::{Error, Visitor},
Deserialize, Serialize,
};
use std::fmt;

impl Serialize for Pem {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&encode(self))
}
}

struct PemVisitor;

impl<'de> Visitor<'de> for PemVisitor {
type Value = Pem;

fn expecting(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
Ok(())
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
parse(v).map_err(Error::custom)
}
}

impl<'de> Deserialize<'de> for Pem {
fn deserialize<D>(deserializer: D) -> Result<Pem, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(PemVisitor)
}
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down Expand Up @@ -613,4 +661,16 @@ RzHX0lkJl9Stshd/7Gbt65/QYq+v+xvAeT0CoyIg

assert_eq!(SAMPLE_LF, encoded);
}

#[cfg(feature = "serde")]
#[test]
fn test_serde() {
let pem = Pem {
tag: String::from("Mock tag"),
contents: "Mock contents".as_bytes().to_vec(),
};
let value = serde_json::to_string_pretty(&pem).unwrap();
let result = serde_json::from_str(&value).unwrap();
assert_eq!(pem, result);
}
}

0 comments on commit 0b37bd8

Please sign in to comment.