ssh_encoding/pem/
encode.rs1use super::{LineEnding, PemLabel, writer::PemWriter};
2use crate::{Encode, Error};
3use core::str;
4
5#[cfg(feature = "alloc")]
6use {super::LINE_WIDTH, alloc::string::String};
7
8#[diagnostic::on_unimplemented(
13 note = "Consider adding impls of `Encode` and `PemLabel` to `{Self}`"
14)]
15pub trait EncodePem: Encode + PemLabel {
16 fn encode_pem<'o>(&self, line_ending: LineEnding, out: &'o mut [u8]) -> Result<&'o str, Error>;
23
24 #[cfg(feature = "alloc")]
30 fn encode_pem_string(&self, line_ending: LineEnding) -> Result<String, Error>;
31}
32
33impl<T: Encode + PemLabel> EncodePem for T {
34 fn encode_pem<'o>(&self, line_ending: LineEnding, out: &'o mut [u8]) -> Result<&'o str, Error> {
35 let mut writer = PemWriter::new(Self::PEM_LABEL, line_ending, out)?;
36 self.encode(&mut writer)?;
37
38 let encoded_len = writer.finish()?;
39 str::from_utf8(&out[..encoded_len]).map_err(Error::from)
40 }
41
42 #[cfg(feature = "alloc")]
43 fn encode_pem_string(&self, line_ending: LineEnding) -> Result<String, Error> {
44 let encoded_len = pem_rfc7468::encapsulated_len_wrapped(
45 Self::PEM_LABEL,
46 LINE_WIDTH,
47 line_ending,
48 self.encoded_len()?,
49 )
50 .map_err(Error::from)?;
51
52 let mut buf = vec![0u8; encoded_len];
53 let actual_len = self.encode_pem(line_ending, &mut buf)?.len();
54 buf.truncate(actual_len);
55 String::from_utf8(buf).map_err(Error::from)
56 }
57}