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}