use std::path::PathBuf;
use crate::error::{Error, Result};
enum Source {
Files { cert: PathBuf, key: PathBuf },
Pem { cert: Vec<u8>, key: Vec<u8> },
}
pub struct TlsConfig {
source: Source,
}
impl std::fmt::Debug for TlsConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.source {
Source::Files { cert, key } => f
.debug_struct("TlsConfig")
.field("cert", cert)
.field("key", key)
.finish(),
Source::Pem { .. } => f.debug_struct("TlsConfig").field("source", &"pem").finish(),
}
}
}
impl TlsConfig {
pub fn from_pem_files(cert: impl Into<PathBuf>, key: impl Into<PathBuf>) -> Self {
Self {
source: Source::Files {
cert: cert.into(),
key: key.into(),
},
}
}
pub fn from_pem(cert_pem: impl Into<Vec<u8>>, key_pem: impl Into<Vec<u8>>) -> Self {
Self {
source: Source::Pem {
cert: cert_pem.into(),
key: key_pem.into(),
},
}
}
pub(crate) fn pem_pair(&self) -> Result<(Vec<u8>, Vec<u8>)> {
match &self.source {
Source::Files { cert, key } => {
let cert = std::fs::read(cert).map_err(|e| {
Error::Config(format!("cannot read TLS cert {}: {e}", cert.display()))
})?;
let key = std::fs::read(key).map_err(|e| {
Error::Config(format!("cannot read TLS key {}: {e}", key.display()))
})?;
Ok((cert, key))
}
Source::Pem { cert, key } => Ok((cert.clone(), key.clone())),
}
}
}