Skip to main content

age_crypto/types/
encrypted_data.rs

1use std::fmt;
2
3/// A newtype over [`Vec<u8>`] representing **binary** (non‑armored) age
4/// encrypted data.
5///
6/// # Overview
7///
8/// This is the raw, binary output of age encryption when no armor is
9/// requested. It is the complement of [`ArmoredData`]. The inner bytes are
10/// the direct result of the `age::Encryptor` writer — a compact, but not
11/// human‑readable, ciphertext.
12///
13/// # Why wrap a `Vec<u8>`?
14///
15/// Exactly the same reasons as `ArmoredData`:
16/// - **Type distinctness** – prevents mixing up plaintext, encrypted data,
17///   and other byte buffers at the type level.
18/// - **Controlled construction** – `new` is `pub(crate)`, so only the
19///   encryption functions can create an `EncryptedData`. This guarantees
20///   that any `EncryptedData` you hold came from a successful encryption
21///   operation.
22/// - **Ergonomics** – implements [`AsRef<[u8]>`], `From` conversions, and
23///   provides accessor methods. The [`Display`] implementation shows only
24///   the byte length to avoid dumping binary data to the screen.
25///
26/// # Examples
27///
28/// ```ignore
29/// use age_crypto::encrypt;
30///
31/// let encrypted: EncryptedData = encrypt(b"secret", &["age1..."]).unwrap();
32/// println!("{}", encrypted);          // [EncryptedData: 512 bytes]
33/// let raw: &[u8] = encrypted.as_bytes();
34/// let owned: Vec<u8> = encrypted.to_vec();
35/// ```
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct EncryptedData(Vec<u8>);
38
39impl EncryptedData {
40    /// Creates a new `EncryptedData` from raw binary ciphertext.
41    ///
42    /// This is `pub(crate)` because it must only be called after a
43    /// successful encryption. The value is taken as‑is; no further
44    /// validation is needed because the `age` library already produced
45    /// a well‑formed ciphertext.
46    #[must_use]
47    pub(crate) fn new(data: Vec<u8>) -> Self {
48        Self(data)
49    }
50
51    /// Returns the binary ciphertext as a byte slice.
52    ///
53    /// This provides read‑only access to the encrypted bytes. Use it when
54    /// you need to write the data to a file or network stream.
55    ///
56    /// # Example
57    ///
58    /// ```ignore
59    /// std::fs::write("data.age", encrypted.as_bytes())?;
60    /// ```
61    #[must_use]
62    pub fn as_bytes(&self) -> &[u8] {
63        &self.0
64    }
65
66    /// Converts the ciphertext into an owned [`Vec<u8>`].
67    ///
68    /// This clones the internal buffer. If you need to take ownership
69    /// without cloning, use [`From<EncryptedData> for Vec<u8>`] instead,
70    /// which consumes the `EncryptedData`.
71    #[must_use]
72    pub fn to_vec(&self) -> Vec<u8> {
73        self.0.clone()
74    }
75
76    /// Returns the number of bytes in the ciphertext.
77    #[must_use]
78    pub fn len(&self) -> usize {
79        self.0.len()
80    }
81
82    /// Returns `true` if the ciphertext is empty.
83    ///
84    /// Note: a valid age encrypted stream is never truly empty because it
85    /// always contains at least a header. However, this method is provided
86    /// for consistency.
87    #[must_use]
88    pub fn is_empty(&self) -> bool {
89        self.0.is_empty()
90    }
91}
92
93// ---------------------------------------------------------------------------
94// Trait implementations
95// ---------------------------------------------------------------------------
96
97/// Allows `&EncryptedData` to be used wherever `&[u8]` is expected.
98///
99/// This means you can pass an `EncryptedData` directly to functions that
100/// take a byte slice, such as `write_all` or `copy_to`.
101impl AsRef<[u8]> for EncryptedData {
102    fn as_ref(&self) -> &[u8] {
103        &self.0
104    }
105}
106
107/// Converts an owned [`Vec<u8>`] into an `EncryptedData`.
108///
109/// **Caution:** No validation is performed. The caller must guarantee
110/// that the bytes constitute a valid age binary ciphertext. In normal
111/// use, only the encryption functions should use this conversion.
112impl From<Vec<u8>> for EncryptedData {
113    fn from(data: Vec<u8>) -> Self {
114        Self(data)
115    }
116}
117
118/// Extracts the raw byte vector from the wrapper.
119///
120/// This consumes the `EncryptedData`, giving you full ownership of the
121/// underlying [`Vec<u8>`] without cloning.
122impl From<EncryptedData> for Vec<u8> {
123    fn from(data: EncryptedData) -> Self {
124        data.0
125    }
126}
127
128/// Displays a description showing the byte length only.
129///
130/// Printing raw binary data is seldom useful and could clutter output
131/// or accidentally expose ciphertext. The `Display` implementation
132/// limits itself to a short, human‑readable summary.
133impl fmt::Display for EncryptedData {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        write!(f, "[EncryptedData: {} bytes]", self.0.len())
136    }
137}