vitaminc_aead/ciphertext/
write_monads.rs1use super::LocalCipherText;
2use crate::Nonce;
3use bytes::BytesMut;
4use vitaminc_protected::{Controlled, Protected};
5
6#[derive(Default)]
7pub struct CipherTextBuilder();
8
9impl CipherTextBuilder {
10 pub fn new() -> Self {
11 Default::default()
12 }
13
14 pub fn append_nonce<const N: usize>(self, nonce: Nonce<N>) -> NonceWritten<N> {
15 NonceWritten(nonce)
16 }
17}
18
19pub struct NonceWritten<const N: usize>(Nonce<N>);
20
21impl<const N: usize> NonceWritten<N> {
22 pub fn append_target_plaintext(
23 self,
24 plaintext: impl Into<Protected<Vec<u8>>>,
25 ) -> PlaintextWritten<N> {
26 PlaintextWritten::new(self.0, plaintext.into())
27 }
28}
29
30pub struct PlaintextWritten<const N: usize>(Nonce<N>, Protected<Vec<u8>>);
31
32impl<const N: usize> PlaintextWritten<N> {
33 fn new(nonce: Nonce<N>, plaintext: Protected<Vec<u8>>) -> Self {
34 Self(nonce, plaintext)
35 }
36
37 pub fn accepts_ciphertext_and_tag_ok<E>(
39 self,
40 f: impl FnOnce(Vec<u8>) -> Result<Vec<u8>, E>,
41 ) -> EncryptedWithTag<N, E> {
42 EncryptedWithTag::new(self.0, self.1.map_ok(f))
43 }
44}
45
46pub struct EncryptedWithTag<const N: usize, E> {
47 nonce: Nonce<N>,
48 bytes: Result<Protected<Vec<u8>>, E>,
49}
50
51impl<const N: usize, E> EncryptedWithTag<N, E> {
52 fn new(nonce: Nonce<N>, bytes: Result<Protected<Vec<u8>>, E>) -> Self {
53 Self { bytes, nonce }
54 }
55
56 pub fn build(self) -> Result<LocalCipherText, E> {
57 let inner = self.bytes?.risky_unwrap();
59 let mut bytes = BytesMut::with_capacity(N + inner.len());
60 bytes.extend(self.nonce.into_inner());
61 bytes.extend(inner);
62 Ok(LocalCipherText(bytes.freeze()))
63 }
64}