#[derive(Clone)]
enum CertFormat {
Pem,
Der,
}
#[derive(Clone)]
pub struct Certificate {
format: CertFormat,
bytes: Vec<u8>,
}
impl Certificate {
pub fn from_pem(bytes: impl Into<Vec<u8>>) -> Self {
Self {
format: CertFormat::Pem,
bytes: bytes.into(),
}
}
pub fn from_der(bytes: impl Into<Vec<u8>>) -> Self {
Self {
format: CertFormat::Der,
bytes: bytes.into(),
}
}
pub(crate) fn bytes(&self) -> &[u8] {
&self.bytes
}
pub(crate) fn is_pem(&self) -> bool {
matches!(self.format, CertFormat::Pem)
}
}
impl std::fmt::Debug for Certificate {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Certificate")
.field("format", &if self.is_pem() { "pem" } else { "der" })
.field("bytes", &format_args!("<{} bytes>", self.bytes.len()))
.finish()
}
}
#[cfg(test)]
mod tests {
use super::Certificate;
#[test]
fn from_pem_stores_bytes_and_marks_pem() {
let cert = Certificate::from_pem(b"data".to_vec());
assert!(cert.is_pem(), "from_pem must mark the cert as PEM");
assert_eq!(cert.bytes(), b"data", "from_pem must store the bytes as-is");
}
#[test]
fn from_der_stores_bytes_and_marks_der() {
let cert = Certificate::from_der(b"data".to_vec());
assert!(!cert.is_pem(), "from_der must NOT be marked as PEM");
assert_eq!(cert.bytes(), b"data", "from_der must store the bytes as-is");
}
}