1use core::marker::PhantomData;
39use std::collections::{BTreeMap, HashMap};
40
41use vitaminc_protected::{Controlled, Protected};
42use zeroize::Zeroize;
43
44use crate::plaintext::{
45 Encrypt, Error, FixedType, Float, Logical, MapSink, Physical, SeqSink, Sink, SourceError,
46};
47use crate::seal::{AsyncCipher, Cipher, Node};
48use crate::walk::{decrypt_into, decrypt_into_async, DecryptError};
49use crate::IntoAad;
50
51#[doc(inline)]
56pub use vitaminc_aead_derive::Decrypt;
57
58#[derive(Debug, thiserror::Error)]
62#[non_exhaustive]
63pub enum DecodeError {
64 #[error("expected {0}")]
66 Expected(&'static str),
67 #[error("unknown key {0:?}")]
69 UnknownKey(String),
70 #[error("duplicate key {0:?}")]
72 DuplicateKey(String),
73 #[error("missing field {0:?}")]
75 MissingField(&'static str),
76 #[error("source failed: {0}")]
78 Source(#[source] SourceError),
79}
80
81impl DecodeError {
82 pub fn unknown_key(key: &str) -> Self {
84 Self::UnknownKey(key.to_owned())
85 }
86
87 pub fn duplicate_key(key: &str) -> Self {
89 Self::DuplicateKey(key.to_owned())
90 }
91}
92
93impl Error for DecodeError {
94 fn source(error: SourceError) -> Self {
95 Self::Source(error)
96 }
97}
98
99pub trait Decrypt: Sized {
101 type Sink: Sink<Ok = Self, Error = DecodeError>;
102
103 fn sink() -> Self::Sink;
104
105 fn reads_null(_: FixedType) -> bool {
111 false
112 }
113}
114
115pub fn decrypt<'a, T, C, A>(
117 cipher: &C,
118 node: Node<C::Leaf>,
119 aad: A,
120) -> Result<T, DecryptError<DecodeError, C::Error>>
121where
122 T: Decrypt,
123 C: Cipher,
124 A: IntoAad<'a>,
125{
126 decrypt_into(cipher, node, aad, T::sink())
127}
128
129pub async fn decrypt_async<'a, T, C, A>(
132 cipher: &C,
133 node: Node<C::Leaf>,
134 aad: A,
135) -> Result<T, DecryptError<DecodeError, C::Error>>
136where
137 T: Decrypt,
138 C: AsyncCipher,
139 A: IntoAad<'a>,
140{
141 decrypt_into_async(cipher, node, aad, T::sink()).await
142}
143
144pub trait FromScalar: Sized {
146 const EXPECTED: &'static str;
148 const FIXED: Option<FixedType> = None;
159 fn from_scalar(ty: Option<Logical>, value: Physical<'_>) -> Option<Self>;
160
161 fn from_scalar_protected(ty: Option<Logical>, value: Physical<'_>) -> Option<Protected<Self>>
167 where
168 Self: Zeroize,
169 {
170 Self::from_scalar(ty, value).map(Protected::new)
171 }
172}
173
174pub struct ScalarSink<T>(PhantomData<T>);
176
177impl<T: FromScalar> Sink for ScalarSink<T> {
178 type Ok = T;
179 type Error = DecodeError;
180 type Seq = Never<T>;
181 type Map = Never<T>;
182
183 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<T, DecodeError> {
184 T::from_scalar(ty, v).ok_or(DecodeError::Expected(T::EXPECTED))
185 }
186
187 fn typed_null(self, _: FixedType) -> Result<T, DecodeError> {
189 Err(DecodeError::Expected(T::EXPECTED))
190 }
191
192 fn seq(self, _: Option<usize>) -> Result<Never<T>, DecodeError> {
193 Err(DecodeError::Expected(T::EXPECTED))
194 }
195
196 fn map(self, _: Option<usize>) -> Result<Never<T>, DecodeError> {
197 Err(DecodeError::Expected(T::EXPECTED))
198 }
199
200 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<T, DecodeError> {
201 Err(DecodeError::Expected(T::EXPECTED))
202 }
203}
204
205impl<T: FromScalar> Decrypt for T {
206 type Sink = ScalarSink<T>;
207 fn sink() -> ScalarSink<T> {
208 ScalarSink(PhantomData)
209 }
210
211 fn reads_null(ty: FixedType) -> bool {
212 T::FIXED == Some(ty) || T::from_scalar(ty.logical(), ty.width().zero()).is_some()
213 }
214}
215
216pub enum Nothing {}
220
221impl Sink for Nothing {
222 type Ok = ();
223 type Error = DecodeError;
224 type Seq = Never<()>;
225 type Map = Never<()>;
226
227 fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<(), DecodeError> {
228 match self {}
229 }
230
231 fn typed_null(self, _: FixedType) -> Result<(), DecodeError> {
232 match self {}
233 }
234
235 fn seq(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
236 match self {}
237 }
238
239 fn map(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
240 match self {}
241 }
242
243 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<(), DecodeError> {
244 match self {}
245 }
246}
247
248pub enum Never<T> {
250 #[doc(hidden)]
251 _Never(core::convert::Infallible, PhantomData<T>),
252}
253
254impl<T> Never<T> {
255 fn absurd<R>(&self) -> R {
256 match *self {
257 Never::_Never(never, _) => match never {},
258 }
259 }
260}
261
262impl<T> SeqSink for Never<T> {
263 type Ok = T;
264 type Error = DecodeError;
265 type Element<'s>
266 = Nothing
267 where
268 Self: 's;
269
270 fn element(&mut self) -> Result<Nothing, DecodeError> {
271 self.absurd()
272 }
273
274 fn end(self) -> Result<T, DecodeError> {
275 self.absurd()
276 }
277}
278
279impl<T> MapSink for Never<T> {
280 type Ok = T;
281 type Error = DecodeError;
282 type Entry<'s>
283 = Nothing
284 where
285 Self: 's;
286
287 fn entry(&mut self, _: &str) -> Result<Nothing, DecodeError> {
288 self.absurd()
289 }
290
291 fn end(self) -> Result<T, DecodeError> {
292 self.absurd()
293 }
294}
295
296macro_rules! int_target {
297 ($($ty:ty),* $(,)?) => {
298 $(
299 impl FromScalar for $ty {
300 const EXPECTED: &'static str = stringify!($ty);
301 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
302 match (ty, v) {
303 (None, Physical::Int(i)) => i
304 .to_i128()
305 .and_then(|v| Self::try_from(v).ok())
306 .or_else(|| i.to_u128().and_then(|v| Self::try_from(v).ok())),
307 _ => None,
308 }
309 }
310 }
311 )*
312 };
313}
314
315int_target!(i8, i16, i32, i64, i128, u16, u32, u64, u128);
318
319impl FromScalar for bool {
320 const EXPECTED: &'static str = "bool";
321 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
322 match (ty, v) {
323 (None, Physical::Bool(b)) => Some(b),
324 _ => None,
325 }
326 }
327}
328
329impl FromScalar for f32 {
330 const EXPECTED: &'static str = "f32";
331 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
332 match (ty, v) {
333 (None, Physical::Float(Float::F32(f))) => Some(f),
334 _ => None,
335 }
336 }
337}
338
339impl FromScalar for f64 {
341 const EXPECTED: &'static str = "f64";
342 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
343 match (ty, v) {
344 (None, Physical::Float(Float::F64(f))) => Some(f),
345 (None, Physical::Float(Float::F32(f))) => Some(f.into()),
346 _ => None,
347 }
348 }
349}
350
351impl FromScalar for String {
352 const EXPECTED: &'static str = "string";
353 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
354 match (ty, v) {
355 (None, Physical::Text(s)) => Some(s.to_owned()),
356 _ => None,
357 }
358 }
359}
360
361impl FromScalar for Vec<u8> {
363 const EXPECTED: &'static str = "bytes";
364 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
365 match (ty, v) {
366 (None, Physical::Bytes(b)) => Some(b.to_vec()),
367 _ => None,
368 }
369 }
370}
371
372impl<const N: usize> FromScalar for [u8; N] {
373 const EXPECTED: &'static str = "byte array";
374 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
375 match (ty, v) {
376 (None, Physical::Bytes(b)) => b.try_into().ok(),
377 _ => None,
378 }
379 }
380
381 fn from_scalar_protected(ty: Option<Logical>, v: Physical<'_>) -> Option<Protected<Self>> {
384 match (ty, v) {
385 (None, Physical::Bytes(b)) if b.len() == N => {
386 let mut out = Protected::new([0u8; N]);
387 out.risky_inner_mut().copy_from_slice(b);
388 Some(out)
389 }
390 _ => None,
391 }
392 }
393}
394
395#[cfg(feature = "chrono")]
396mod chrono_targets {
397 use super::*;
398 use crate::plaintext::kinds::chrono as conv;
399 use ::chrono::{DateTime, NaiveDate, Utc};
400
401 impl FromScalar for NaiveDate {
402 const EXPECTED: &'static str = "date";
403 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
404 match (ty, v) {
405 (Some(Logical::Date), Physical::Int(days)) => conv::date(days),
406 _ => None,
407 }
408 }
409 }
410
411 impl FromScalar for DateTime<Utc> {
414 const EXPECTED: &'static str = "timestamp";
415 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
416 match (ty, v) {
417 (Some(Logical::Timestamp(unit)), Physical::Int(count)) => {
418 conv::timestamp(unit, count)
419 }
420 _ => None,
421 }
422 }
423 }
424}
425
426#[cfg(feature = "rust_decimal")]
427impl FromScalar for rust_decimal::Decimal {
428 const EXPECTED: &'static str = "decimal";
429 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
430 match (ty, v) {
431 (Some(Logical::Decimal { scale }), Physical::Int(mantissa)) => {
432 crate::plaintext::kinds::decimal::decimal(scale, mantissa)
433 }
434 _ => None,
435 }
436 }
437}
438
439#[cfg(feature = "uuid")]
440impl FromScalar for uuid::Uuid {
441 const EXPECTED: &'static str = "uuid";
442 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
443 match (ty, v) {
444 (Some(Logical::Uuid), Physical::Bytes(b)) => uuid::Uuid::from_slice(b).ok(),
445 _ => None,
446 }
447 }
448}
449
450pub trait Put<T> {
452 fn put(self, value: T);
453}
454
455pub struct Push<'s, T>(pub &'s mut Vec<T>);
457
458impl<T> Put<T> for Push<'_, T> {
459 fn put(self, value: T) {
460 self.0.push(value);
461 }
462}
463
464pub struct Insert<'s, M>(pub &'s mut M, pub String);
466
467impl<T> Put<T> for Insert<'_, HashMap<String, T>> {
468 fn put(self, value: T) {
469 self.0.insert(self.1, value);
470 }
471}
472
473impl<T> Put<T> for Insert<'_, BTreeMap<String, T>> {
474 fn put(self, value: T) {
475 self.0.insert(self.1, value);
476 }
477}
478
479pub struct Slot<'s, T>(pub &'s mut Option<T>);
481
482impl<T> Put<T> for Slot<'_, T> {
483 fn put(self, value: T) {
484 *self.0 = Some(value);
485 }
486}
487
488pub struct Forward<T: Decrypt, O>(pub T::Sink, pub O);
491
492impl<T: Decrypt, O: Put<T>> Sink for Forward<T, O> {
493 type Ok = ();
494 type Error = DecodeError;
495 type Seq = ForwardEnd<T, <T::Sink as Sink>::Seq, O>;
496 type Map = ForwardEnd<T, <T::Sink as Sink>::Map, O>;
497
498 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<(), DecodeError> {
499 self.1.put(self.0.scalar(ty, v)?);
500 Ok(())
501 }
502
503 fn typed_null(self, ty: FixedType) -> Result<(), DecodeError> {
504 self.1.put(self.0.typed_null(ty)?);
505 Ok(())
506 }
507
508 fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
509 Ok(ForwardEnd(self.0.seq(len)?, self.1, PhantomData))
510 }
511
512 fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
513 Ok(ForwardEnd(self.0.map(len)?, self.1, PhantomData))
514 }
515
516 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<(), DecodeError> {
517 self.1.put(self.0.passthrough(value)?);
518 Ok(())
519 }
520}
521
522pub struct ForwardEnd<T, Q, O>(Q, O, PhantomData<T>);
524
525impl<T, Q: SeqSink<Ok = T, Error = DecodeError>, O: Put<T>> SeqSink for ForwardEnd<T, Q, O> {
526 type Ok = ();
527 type Error = DecodeError;
528 type Element<'e>
529 = Q::Element<'e>
530 where
531 Self: 'e;
532
533 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
534 self.0.element()
535 }
536
537 fn end(self) -> Result<(), DecodeError> {
538 self.1.put(self.0.end()?);
539 Ok(())
540 }
541}
542
543impl<T, Q: MapSink<Ok = T, Error = DecodeError>, O: Put<T>> MapSink for ForwardEnd<T, Q, O> {
544 type Ok = ();
545 type Error = DecodeError;
546 type Entry<'e>
547 = Q::Entry<'e>
548 where
549 Self: 'e;
550
551 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
552 self.0.entry(key)
553 }
554
555 fn end(self) -> Result<(), DecodeError> {
556 self.1.put(self.0.end()?);
557 Ok(())
558 }
559}
560
561pub enum Either<L, R> {
569 Left(L),
570 Right(R),
571}
572
573impl<L: Sink, R: Sink<Error = L::Error>> Sink for Either<L, R> {
574 type Ok = Either<L::Ok, R::Ok>;
575 type Error = L::Error;
576 type Seq = Either<L::Seq, R::Seq>;
577 type Map = Either<L::Map, R::Map>;
578
579 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Self::Ok, Self::Error> {
580 match self {
581 Either::Left(l) => l.scalar(ty, v).map(Either::Left),
582 Either::Right(r) => r.scalar(ty, v).map(Either::Right),
583 }
584 }
585
586 fn typed_null(self, ty: FixedType) -> Result<Self::Ok, Self::Error> {
587 match self {
588 Either::Left(l) => l.typed_null(ty).map(Either::Left),
589 Either::Right(r) => r.typed_null(ty).map(Either::Right),
590 }
591 }
592
593 fn seq(self, len: Option<usize>) -> Result<Self::Seq, Self::Error> {
594 match self {
595 Either::Left(l) => l.seq(len).map(Either::Left),
596 Either::Right(r) => r.seq(len).map(Either::Right),
597 }
598 }
599
600 fn map(self, len: Option<usize>) -> Result<Self::Map, Self::Error> {
601 match self {
602 Either::Left(l) => l.map(len).map(Either::Left),
603 Either::Right(r) => r.map(len).map(Either::Right),
604 }
605 }
606
607 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Self::Ok, Self::Error> {
608 match self {
609 Either::Left(l) => l.passthrough(value).map(Either::Left),
610 Either::Right(r) => r.passthrough(value).map(Either::Right),
611 }
612 }
613}
614
615impl<L: SeqSink, R: SeqSink<Error = L::Error>> SeqSink for Either<L, R> {
616 type Ok = Either<L::Ok, R::Ok>;
617 type Error = L::Error;
618 type Element<'s>
619 = Either<L::Element<'s>, R::Element<'s>>
620 where
621 Self: 's;
622
623 fn element(&mut self) -> Result<Self::Element<'_>, Self::Error> {
624 match self {
625 Either::Left(l) => l.element().map(Either::Left),
626 Either::Right(r) => r.element().map(Either::Right),
627 }
628 }
629
630 fn end(self) -> Result<Self::Ok, Self::Error> {
631 match self {
632 Either::Left(l) => l.end().map(Either::Left),
633 Either::Right(r) => r.end().map(Either::Right),
634 }
635 }
636}
637
638impl<L: MapSink, R: MapSink<Error = L::Error>> MapSink for Either<L, R> {
639 type Ok = Either<L::Ok, R::Ok>;
640 type Error = L::Error;
641 type Entry<'s>
642 = Either<L::Entry<'s>, R::Entry<'s>>
643 where
644 Self: 's;
645
646 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, Self::Error> {
647 match self {
648 Either::Left(l) => l.entry(key).map(Either::Left),
649 Either::Right(r) => r.entry(key).map(Either::Right),
650 }
651 }
652
653 fn end(self) -> Result<Self::Ok, Self::Error> {
654 match self {
655 Either::Left(l) => l.end().map(Either::Left),
656 Either::Right(r) => r.end().map(Either::Right),
657 }
658 }
659}
660
661pub struct Clear<T: Decrypt, O>(O, PhantomData<T>);
668
669impl<T: Decrypt, O: Put<T>> Clear<T, O> {
670 pub fn new(out: O) -> Self {
671 Self(out, PhantomData)
672 }
673}
674
675impl<T: Decrypt, O: Put<T>> Sink for Clear<T, O> {
676 type Ok = ();
677 type Error = DecodeError;
678 type Seq = Never<()>;
679 type Map = Never<()>;
680
681 fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<(), DecodeError> {
682 Err(DecodeError::Expected("passthrough"))
683 }
684
685 fn typed_null(self, _: FixedType) -> Result<(), DecodeError> {
686 Err(DecodeError::Expected("passthrough"))
687 }
688
689 fn seq(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
690 Err(DecodeError::Expected("passthrough"))
691 }
692
693 fn map(self, _: Option<usize>) -> Result<Never<()>, DecodeError> {
694 Err(DecodeError::Expected("passthrough"))
695 }
696
697 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<(), DecodeError> {
698 self.0.put(value.visit(T::sink())?);
699 Ok(())
700 }
701}
702
703pub trait Rewrap<T> {
708 type Output;
709 fn rewrap(value: T) -> Result<Self::Output, DecodeError>;
710}
711
712pub struct Wrapped<S, W>(S, PhantomData<W>);
715
716impl<S, W> Wrapped<S, W> {
717 pub fn new(sink: S) -> Self {
718 Self(sink, PhantomData)
719 }
720}
721
722impl<S: Sink<Error = DecodeError>, W: Rewrap<S::Ok>> Sink for Wrapped<S, W> {
723 type Ok = W::Output;
724 type Error = DecodeError;
725 type Seq = WrappedEnd<S::Seq, W>;
726 type Map = WrappedEnd<S::Map, W>;
727
728 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<W::Output, DecodeError> {
729 self.0.scalar(ty, v).and_then(W::rewrap)
730 }
731
732 fn typed_null(self, ty: FixedType) -> Result<W::Output, DecodeError> {
733 self.0.typed_null(ty).and_then(W::rewrap)
734 }
735
736 fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
737 Ok(WrappedEnd(self.0.seq(len)?, PhantomData))
738 }
739
740 fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
741 Ok(WrappedEnd(self.0.map(len)?, PhantomData))
742 }
743
744 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<W::Output, DecodeError> {
745 self.0.passthrough(value).and_then(W::rewrap)
746 }
747}
748
749pub struct WrappedEnd<Q, W>(Q, PhantomData<W>);
751
752impl<Q: SeqSink<Error = DecodeError>, W: Rewrap<Q::Ok>> SeqSink for WrappedEnd<Q, W> {
753 type Ok = W::Output;
754 type Error = DecodeError;
755 type Element<'e>
756 = Q::Element<'e>
757 where
758 Self: 'e;
759
760 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
761 self.0.element()
762 }
763
764 fn end(self) -> Result<W::Output, DecodeError> {
765 self.0.end().and_then(W::rewrap)
766 }
767}
768
769impl<Q: MapSink<Error = DecodeError>, W: Rewrap<Q::Ok>> MapSink for WrappedEnd<Q, W> {
770 type Ok = W::Output;
771 type Error = DecodeError;
772 type Entry<'e>
773 = Q::Entry<'e>
774 where
775 Self: 'e;
776
777 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
778 self.0.entry(key)
779 }
780
781 fn end(self) -> Result<W::Output, DecodeError> {
782 self.0.end().and_then(W::rewrap)
783 }
784}
785
786pub struct List<T>(PhantomData<T>);
788
789impl<T: Decrypt> Sink for List<T> {
790 type Ok = Vec<T>;
791 type Error = DecodeError;
792 type Seq = ListSeq<T>;
793 type Map = Never<Vec<T>>;
794
795 fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Vec<T>, DecodeError> {
796 Err(DecodeError::Expected("sequence"))
797 }
798
799 fn typed_null(self, _: FixedType) -> Result<Vec<T>, DecodeError> {
800 Err(DecodeError::Expected("sequence"))
801 }
802
803 fn seq(self, len: Option<usize>) -> Result<ListSeq<T>, DecodeError> {
804 Ok(ListSeq(Vec::with_capacity(len.unwrap_or(0).min(1024))))
805 }
806
807 fn map(self, _: Option<usize>) -> Result<Never<Vec<T>>, DecodeError> {
808 Err(DecodeError::Expected("sequence"))
809 }
810
811 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Vec<T>, DecodeError> {
812 Err(DecodeError::Expected("sequence"))
813 }
814}
815
816pub struct ListSeq<T>(Vec<T>);
817
818impl<T: Decrypt> SeqSink for ListSeq<T> {
819 type Ok = Vec<T>;
820 type Error = DecodeError;
821 type Element<'s>
822 = Forward<T, Push<'s, T>>
823 where
824 Self: 's;
825
826 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
827 Ok(Forward(T::sink(), Push(&mut self.0)))
828 }
829
830 fn end(self) -> Result<Vec<T>, DecodeError> {
831 Ok(self.0)
832 }
833}
834
835impl<T: Decrypt> Decrypt for Vec<T> {
836 type Sink = List<T>;
837 fn sink() -> List<T> {
838 List(PhantomData)
839 }
840}
841
842pub struct Dict<M>(PhantomData<M>);
845
846pub struct DictEntries<M>(M);
848
849macro_rules! dict_target {
850 ($($map:ident),*) => {
851 $(
852 impl<T: Decrypt> Sink for Dict<$map<String, T>> {
853 type Ok = $map<String, T>;
854 type Error = DecodeError;
855 type Seq = Never<$map<String, T>>;
856 type Map = DictEntries<$map<String, T>>;
857
858 fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Self::Ok, DecodeError> {
859 Err(DecodeError::Expected("map"))
860 }
861
862 fn typed_null(self, _: FixedType) -> Result<Self::Ok, DecodeError> {
863 Err(DecodeError::Expected("map"))
864 }
865
866 fn seq(self, _: Option<usize>) -> Result<Self::Seq, DecodeError> {
867 Err(DecodeError::Expected("map"))
868 }
869
870 fn map(self, _: Option<usize>) -> Result<Self::Map, DecodeError> {
871 Ok(DictEntries($map::new()))
872 }
873
874 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Self::Ok, DecodeError> {
875 Err(DecodeError::Expected("map"))
876 }
877 }
878
879 impl<T: Decrypt> MapSink for DictEntries<$map<String, T>> {
880 type Ok = $map<String, T>;
881 type Error = DecodeError;
882 type Entry<'s>
883 = Forward<T, Insert<'s, $map<String, T>>>
884 where
885 Self: 's;
886
887 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
888 Ok(Forward(T::sink(), Insert(&mut self.0, key.to_owned())))
889 }
890
891 fn end(self) -> Result<Self::Ok, DecodeError> {
892 Ok(self.0)
893 }
894 }
895
896 impl<T: Decrypt> Decrypt for $map<String, T> {
897 type Sink = Dict<$map<String, T>>;
898 fn sink() -> Self::Sink {
899 Dict(PhantomData)
900 }
901 }
902 )*
903 };
904}
905
906dict_target!(HashMap, BTreeMap);
907
908pub struct Optional<T: Decrypt>(T::Sink);
916
917impl<T: Decrypt> Sink for Optional<T> {
918 type Ok = Option<T>;
919 type Error = DecodeError;
920 type Seq = Some_<T, <T::Sink as Sink>::Seq>;
921 type Map = Some_<T, <T::Sink as Sink>::Map>;
922
923 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Option<T>, DecodeError> {
924 match (ty, v) {
925 (None | Some(Logical::Undefined), Physical::Null) => Ok(None),
926 _ => self.0.scalar(ty, v).map(Some),
927 }
928 }
929
930 fn typed_null(self, ty: FixedType) -> Result<Option<T>, DecodeError> {
931 if T::reads_null(ty) {
932 return Ok(None);
933 }
934 self.0.typed_null(ty).map(Some)
935 }
936
937 fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
938 Ok(Some_(self.0.seq(len)?, PhantomData))
939 }
940
941 fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
942 Ok(Some_(self.0.map(len)?, PhantomData))
943 }
944
945 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Option<T>, DecodeError> {
946 self.0.passthrough(value).map(Some)
947 }
948}
949
950pub struct Some_<T, Q>(Q, PhantomData<T>);
952
953impl<T, Q: SeqSink<Ok = T, Error = DecodeError>> SeqSink for Some_<T, Q> {
954 type Ok = Option<T>;
955 type Error = DecodeError;
956 type Element<'e>
957 = Q::Element<'e>
958 where
959 Self: 'e;
960
961 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
962 self.0.element()
963 }
964
965 fn end(self) -> Result<Option<T>, DecodeError> {
966 self.0.end().map(Some)
967 }
968}
969
970impl<T, Q: MapSink<Ok = T, Error = DecodeError>> MapSink for Some_<T, Q> {
971 type Ok = Option<T>;
972 type Error = DecodeError;
973 type Entry<'e>
974 = Q::Entry<'e>
975 where
976 Self: 'e;
977
978 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
979 self.0.entry(key)
980 }
981
982 fn end(self) -> Result<Option<T>, DecodeError> {
983 self.0.end().map(Some)
984 }
985}
986
987impl<T: Decrypt> Decrypt for Option<T> {
988 type Sink = Optional<T>;
989 fn sink() -> Optional<T> {
990 Optional(T::sink())
991 }
992
993 fn reads_null(ty: FixedType) -> bool {
994 T::reads_null(ty)
995 }
996}
997
998pub trait DecryptProtected: Decrypt + Zeroize {
1007 type ProtectedSink: Sink<Ok = Protected<Self>, Error = DecodeError>;
1008 fn protected_sink() -> Self::ProtectedSink;
1009}
1010
1011impl<T: DecryptProtected> Decrypt for Protected<T> {
1012 type Sink = T::ProtectedSink;
1013 fn sink() -> T::ProtectedSink {
1014 T::protected_sink()
1015 }
1016
1017 fn reads_null(ty: FixedType) -> bool {
1018 T::reads_null(ty)
1019 }
1020}
1021
1022impl<T: FromScalar + Zeroize> DecryptProtected for T {
1028 type ProtectedSink = ScalarProtected<T>;
1029 fn protected_sink() -> ScalarProtected<T> {
1030 ScalarProtected(PhantomData)
1031 }
1032}
1033
1034pub struct ScalarProtected<T>(PhantomData<T>);
1037
1038impl<T: FromScalar + Zeroize> Sink for ScalarProtected<T> {
1039 type Ok = Protected<T>;
1040 type Error = DecodeError;
1041 type Seq = Never<Protected<T>>;
1042 type Map = Never<Protected<T>>;
1043
1044 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Protected<T>, DecodeError> {
1045 T::from_scalar_protected(ty, v).ok_or(DecodeError::Expected(T::EXPECTED))
1046 }
1047
1048 fn typed_null(self, _: FixedType) -> Result<Protected<T>, DecodeError> {
1049 Err(DecodeError::Expected(T::EXPECTED))
1050 }
1051
1052 fn seq(self, _: Option<usize>) -> Result<Self::Seq, DecodeError> {
1053 Err(DecodeError::Expected(T::EXPECTED))
1054 }
1055
1056 fn map(self, _: Option<usize>) -> Result<Self::Map, DecodeError> {
1057 Err(DecodeError::Expected(T::EXPECTED))
1058 }
1059
1060 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Protected<T>, DecodeError> {
1061 Err(DecodeError::Expected(T::EXPECTED))
1062 }
1063}
1064
1065impl<T: DecryptProtected> DecryptProtected for Vec<T> {
1072 type ProtectedSink = ProtectedList<T>;
1073 fn protected_sink() -> ProtectedList<T> {
1074 ProtectedList(PhantomData)
1075 }
1076}
1077
1078pub struct ProtectedList<T>(PhantomData<T>);
1080
1081impl<T: DecryptProtected> Sink for ProtectedList<T> {
1082 type Ok = Protected<Vec<T>>;
1083 type Error = DecodeError;
1084 type Seq = ProtectedListSeq<T>;
1085 type Map = Never<Protected<Vec<T>>>;
1086
1087 fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Self::Ok, DecodeError> {
1088 Err(DecodeError::Expected("sequence"))
1089 }
1090
1091 fn typed_null(self, _: FixedType) -> Result<Self::Ok, DecodeError> {
1092 Err(DecodeError::Expected("sequence"))
1093 }
1094
1095 fn seq(self, len: Option<usize>) -> Result<ProtectedListSeq<T>, DecodeError> {
1096 let items = Vec::with_capacity(len.unwrap_or(0).min(1024));
1097 Ok(ProtectedListSeq(Protected::new(items)))
1098 }
1099
1100 fn map(self, _: Option<usize>) -> Result<Self::Map, DecodeError> {
1101 Err(DecodeError::Expected("sequence"))
1102 }
1103
1104 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Self::Ok, DecodeError> {
1105 Err(DecodeError::Expected("sequence"))
1106 }
1107}
1108
1109pub struct ProtectedListSeq<T: Zeroize>(Protected<Vec<T>>);
1112
1113impl<T: DecryptProtected> SeqSink for ProtectedListSeq<T> {
1114 type Ok = Protected<Vec<T>>;
1115 type Error = DecodeError;
1116 type Element<'s>
1117 = Forward<Protected<T>, ProtectedPush<'s, T>>
1118 where
1119 Self: 's;
1120
1121 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
1122 Ok(Forward(
1123 T::protected_sink(),
1124 ProtectedPush(self.0.risky_inner_mut()),
1125 ))
1126 }
1127
1128 fn end(self) -> Result<Protected<Vec<T>>, DecodeError> {
1129 Ok(self.0)
1130 }
1131}
1132
1133pub struct ProtectedPush<'s, T: Zeroize>(&'s mut Vec<T>);
1137
1138impl<T: Zeroize> Put<Protected<T>> for ProtectedPush<'_, T> {
1139 fn put(self, value: Protected<T>) {
1140 if self.0.len() == self.0.capacity() {
1141 let mut grown = Vec::with_capacity(self.0.capacity().max(4) * 2);
1142 grown.append(self.0);
1143 self.0.zeroize();
1145 *self.0 = grown;
1146 }
1147 self.0.push(value.risky_unwrap());
1148 }
1149}
1150
1151impl<T: DecryptProtected> DecryptProtected for Option<T> {
1154 type ProtectedSink = ProtectedOptional<T>;
1155 fn protected_sink() -> ProtectedOptional<T> {
1156 ProtectedOptional(T::protected_sink())
1157 }
1158}
1159
1160pub struct ProtectedOptional<T: DecryptProtected>(T::ProtectedSink);
1162
1163impl<T: DecryptProtected> Sink for ProtectedOptional<T> {
1164 type Ok = Protected<Option<T>>;
1165 type Error = DecodeError;
1166 type Seq = SomeProtected<T, <T::ProtectedSink as Sink>::Seq>;
1167 type Map = SomeProtected<T, <T::ProtectedSink as Sink>::Map>;
1168
1169 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Self::Ok, DecodeError> {
1170 match (ty, v) {
1171 (None | Some(Logical::Undefined), Physical::Null) => Ok(Protected::new(None)),
1172 _ => self.0.scalar(ty, v).map(some),
1173 }
1174 }
1175
1176 fn typed_null(self, ty: FixedType) -> Result<Self::Ok, DecodeError> {
1177 if T::reads_null(ty) {
1178 return Ok(Protected::new(None));
1179 }
1180 self.0.typed_null(ty).map(some)
1181 }
1182
1183 fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
1184 Ok(SomeProtected(self.0.seq(len)?, PhantomData))
1185 }
1186
1187 fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
1188 Ok(SomeProtected(self.0.map(len)?, PhantomData))
1189 }
1190
1191 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Self::Ok, DecodeError> {
1192 self.0.passthrough(value).map(some)
1193 }
1194}
1195
1196fn some<T: Zeroize>(value: Protected<T>) -> Protected<Option<T>> {
1198 value.map(Some)
1199}
1200
1201pub struct Wrap<S>(pub S);
1210
1211impl<S> Sink for Wrap<S>
1212where
1213 S: Sink<Error = DecodeError>,
1214 S::Ok: Zeroize,
1215{
1216 type Ok = Protected<S::Ok>;
1217 type Error = DecodeError;
1218 type Seq = WrapEnd<S::Seq>;
1219 type Map = WrapEnd<S::Map>;
1220
1221 fn scalar(self, ty: Option<Logical>, v: Physical<'_>) -> Result<Self::Ok, DecodeError> {
1222 self.0.scalar(ty, v).map(Protected::new)
1223 }
1224
1225 fn typed_null(self, ty: FixedType) -> Result<Self::Ok, DecodeError> {
1226 self.0.typed_null(ty).map(Protected::new)
1227 }
1228
1229 fn seq(self, len: Option<usize>) -> Result<Self::Seq, DecodeError> {
1230 Ok(WrapEnd(self.0.seq(len)?))
1231 }
1232
1233 fn map(self, len: Option<usize>) -> Result<Self::Map, DecodeError> {
1234 Ok(WrapEnd(self.0.map(len)?))
1235 }
1236
1237 fn passthrough<P: Encrypt + Clone>(self, value: P) -> Result<Self::Ok, DecodeError> {
1238 self.0.passthrough(value).map(Protected::new)
1239 }
1240}
1241
1242pub struct WrapEnd<Q>(Q);
1244
1245impl<Q> SeqSink for WrapEnd<Q>
1246where
1247 Q: SeqSink<Error = DecodeError>,
1248 Q::Ok: Zeroize,
1249{
1250 type Ok = Protected<Q::Ok>;
1251 type Error = DecodeError;
1252 type Element<'e>
1253 = Q::Element<'e>
1254 where
1255 Self: 'e;
1256
1257 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
1258 self.0.element()
1259 }
1260
1261 fn end(self) -> Result<Self::Ok, DecodeError> {
1262 self.0.end().map(Protected::new)
1263 }
1264}
1265
1266impl<Q> MapSink for WrapEnd<Q>
1267where
1268 Q: MapSink<Error = DecodeError>,
1269 Q::Ok: Zeroize,
1270{
1271 type Ok = Protected<Q::Ok>;
1272 type Error = DecodeError;
1273 type Entry<'e>
1274 = Q::Entry<'e>
1275 where
1276 Self: 'e;
1277
1278 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
1279 self.0.entry(key)
1280 }
1281
1282 fn end(self) -> Result<Self::Ok, DecodeError> {
1283 self.0.end().map(Protected::new)
1284 }
1285}
1286
1287pub struct SomeProtected<T, Q>(Q, PhantomData<T>);
1290
1291impl<T, Q> SeqSink for SomeProtected<T, Q>
1292where
1293 T: Zeroize,
1294 Q: SeqSink<Ok = Protected<T>, Error = DecodeError>,
1295{
1296 type Ok = Protected<Option<T>>;
1297 type Error = DecodeError;
1298 type Element<'e>
1299 = Q::Element<'e>
1300 where
1301 Self: 'e;
1302
1303 fn element(&mut self) -> Result<Self::Element<'_>, DecodeError> {
1304 self.0.element()
1305 }
1306
1307 fn end(self) -> Result<Protected<Option<T>>, DecodeError> {
1308 self.0.end().map(some)
1309 }
1310}
1311
1312impl<T, Q> MapSink for SomeProtected<T, Q>
1313where
1314 T: Zeroize,
1315 Q: MapSink<Ok = Protected<T>, Error = DecodeError>,
1316{
1317 type Ok = Protected<Option<T>>;
1318 type Error = DecodeError;
1319 type Entry<'e>
1320 = Q::Entry<'e>
1321 where
1322 Self: 'e;
1323
1324 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
1325 self.0.entry(key)
1326 }
1327
1328 fn end(self) -> Result<Protected<Option<T>>, DecodeError> {
1329 self.0.end().map(some)
1330 }
1331}
1332
1333#[cfg(test)]
1334mod tests {
1335 use super::*;
1336 use crate::plaintext::{Int, Raw, Width};
1337 use crate::seal::mock::{Mock, Remote};
1338 use crate::{encrypt, encrypt_async};
1339 use futures_executor::block_on;
1340
1341 fn round_trip<T: Decrypt>(
1342 p: impl Encrypt,
1343 ) -> Result<T, DecryptError<DecodeError, crate::seal::mock::Refused>> {
1344 decrypt(&Mock, encrypt(p, &Mock, "ctx").expect("encrypts"), "ctx")
1345 }
1346
1347 fn expected<T>(
1348 r: Result<T, DecryptError<DecodeError, crate::seal::mock::Refused>>,
1349 ) -> &'static str {
1350 match r {
1351 Err(DecryptError::Sink(DecodeError::Expected(what))) => what,
1352 Err(other) => panic!("{other:?}"),
1353 Ok(_) => panic!("decoded"),
1354 }
1355 }
1356
1357 #[test]
1358 fn scalars_round_trip() {
1359 assert_eq!(round_trip::<u32>(34u32).expect("u32"), 34);
1360 assert_eq!(round_trip::<i128>(-5i64).expect("i128"), -5);
1361 assert!(round_trip::<bool>(true).expect("bool"));
1362 assert_eq!(round_trip::<f64>(2.5f64).expect("f64"), 2.5);
1363 assert_eq!(round_trip::<f64>(2.5f32).expect("f64 from f32"), 2.5);
1364 assert_eq!(round_trip::<String>("Ada").expect("string"), "Ada");
1365 assert_eq!(round_trip::<Vec<u8>>(vec![1u8, 2]).expect("bytes"), [1, 2]);
1366 assert_eq!(round_trip::<[u8; 2]>(vec![1u8, 2]).expect("array"), [1, 2]);
1367 assert_eq!(
1368 round_trip::<Protected<String>>(Protected::new(String::from("pw")))
1369 .expect("protected")
1370 .risky_ref(),
1371 "pw"
1372 );
1373 assert_eq!(
1374 round_trip::<Protected<Vec<u8>>>(vec![9u8])
1375 .expect("protected")
1376 .risky_ref(),
1377 &[9]
1378 );
1379 }
1380
1381 #[test]
1382 fn integer_targets_read_the_value_not_the_width() {
1383 assert_eq!(round_trip::<u32>(34i8).expect("widens"), 34);
1384 assert_eq!(round_trip::<i8>(34u64).expect("narrows"), 34);
1385 assert_eq!(
1386 round_trip::<u128>(Raw(None, Physical::Int(Int::U128(u128::MAX)))).expect("u128"),
1387 u128::MAX
1388 );
1389 assert_eq!(expected(round_trip::<u32>(-1i8)), "u32");
1390 assert_eq!(expected(round_trip::<i8>(300u16)), "i8");
1391 assert_eq!(
1392 expected(round_trip::<i128>(Raw(
1393 None,
1394 Physical::Int(Int::U128(u128::MAX))
1395 ))),
1396 "i128"
1397 );
1398 }
1399
1400 #[test]
1401 fn the_wrong_kind_is_refused_by_name() {
1402 assert_eq!(expected(round_trip::<String>(34u32)), "string");
1403 assert_eq!(expected(round_trip::<u32>("34")), "u32");
1404 assert_eq!(expected(round_trip::<f32>(2.5f64)), "f32");
1405 assert_eq!(expected(round_trip::<bool>(vec![true])), "bool");
1406 assert_eq!(expected(round_trip::<Vec<u32>>(34u32)), "sequence");
1407 assert_eq!(expected(round_trip::<[u8; 4]>(vec![1u8, 2])), "byte array");
1408 assert_eq!(
1410 expected(round_trip::<i32>(Raw(
1411 Some(Logical::Date),
1412 Physical::Int(Int::I32(0))
1413 ))),
1414 "i32"
1415 );
1416 }
1417
1418 #[test]
1419 fn containers_round_trip() {
1420 assert_eq!(
1421 round_trip::<Vec<String>>(vec!["Ada", "Grace"]).expect("strings"),
1422 ["Ada", "Grace"]
1423 );
1424 assert_eq!(
1425 round_trip::<Vec<Vec<u32>>>(vec![vec![1u32, 2], vec![], vec![3]]).expect("nested"),
1426 [vec![1, 2], vec![], vec![3]]
1427 );
1428 assert_eq!(
1429 round_trip::<Vec<u32>>(Vec::<u32>::new()).expect("empty"),
1430 Vec::<u32>::new()
1431 );
1432 }
1433
1434 struct Null(FixedType);
1436
1437 impl Encrypt for Null {
1438 fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1439 sink.typed_null(self.0)
1440 }
1441 }
1442
1443 fn plain(width: Width) -> FixedType {
1444 FixedType::plain(width).expect("fixed")
1445 }
1446
1447 #[test]
1448 fn a_typed_null_reads_as_none_for_an_option_of_a_type_that_reads_its_values() {
1449 assert_eq!(round_trip::<Option<u32>>(None::<u32>).expect("u32"), None);
1451 assert_eq!(round_trip::<Option<i8>>(None::<i8>).expect("i8"), None);
1452 assert_eq!(round_trip::<Option<f32>>(None::<f32>).expect("f32"), None);
1453 assert_eq!(
1454 round_trip::<Option<Option<i64>>>(None::<i64>).expect("nested"),
1455 None
1456 );
1457 assert_eq!(
1458 round_trip::<Vec<Option<u16>>>(vec![None, Some(3u16)]).expect("elements"),
1459 [None, Some(3)]
1460 );
1461 assert_eq!(round_trip::<Option<u64>>(None::<u32>).expect("wider"), None);
1463 assert_eq!(
1464 round_trip::<Option<i8>>(None::<u64>).expect("narrower"),
1465 None
1466 );
1467 assert_eq!(round_trip::<Option<f64>>(None::<f32>).expect("f64"), None);
1468 }
1469
1470 #[test]
1471 fn a_typed_null_of_a_type_the_target_does_not_read_is_the_wrong_kind() {
1472 let u32_null = || Null(plain(Width::U32));
1473 assert_eq!(expected(round_trip::<Option<f32>>(u32_null())), "f32");
1474 assert_eq!(expected(round_trip::<Option<String>>(u32_null())), "string");
1475 assert_eq!(expected(round_trip::<Option<Vec<u8>>>(u32_null())), "bytes");
1476 assert_eq!(
1477 expected(round_trip::<Option<Vec<u32>>>(u32_null())),
1478 "sequence"
1479 );
1480 assert_eq!(expected(round_trip::<Option<f32>>(None::<f64>)), "f32");
1481 assert_eq!(expected(round_trip::<Option<u32>>(None::<f32>)), "u32");
1482 let date = FixedType::new(Some(Logical::Date), Width::I32).expect("fixed");
1484 assert_eq!(expected(round_trip::<Option<i32>>(Null(date))), "i32");
1485 }
1486
1487 #[test]
1488 fn a_typed_null_is_not_a_value() {
1489 assert_eq!(expected(round_trip::<u32>(None::<u32>)), "u32");
1490 assert_eq!(expected(round_trip::<f64>(None::<f64>)), "f64");
1491 assert_eq!(expected(round_trip::<Vec<u32>>(None::<u32>)), "sequence");
1492 assert_eq!(
1493 expected(round_trip::<HashMap<String, u32>>(None::<u32>)),
1494 "map"
1495 );
1496 assert_eq!(expected(round_trip::<Protected<u32>>(None::<u32>)), "u32");
1497 }
1498
1499 #[test]
1500 fn the_plain_null_still_reads_as_none_for_any_option() {
1501 assert_eq!(
1504 round_trip::<Option<u32>>(Raw(None, Physical::Null)).expect("u32"),
1505 None
1506 );
1507 assert_eq!(
1508 round_trip::<Protected<Option<u32>>>(Raw(None, Physical::Null))
1509 .expect("protected")
1510 .risky_ref(),
1511 &None
1512 );
1513 }
1514
1515 #[test]
1516 fn a_protected_option_reads_its_typed_null() {
1517 assert_eq!(
1518 round_trip::<Protected<Option<u32>>>(None::<u32>)
1519 .expect("none")
1520 .risky_ref(),
1521 &None
1522 );
1523 assert_eq!(
1524 expected(round_trip::<Protected<Option<f32>>>(None::<u32>)),
1525 "f32"
1526 );
1527 }
1528
1529 #[test]
1531 fn every_target_reads_its_own_sources_none() {
1532 fn own<T: Encrypt + Decrypt>() {
1533 let ty = <T as Encrypt>::FIXED.expect("fixed width");
1534 assert!(<T as Decrypt>::reads_null(ty), "{ty:?}");
1535 assert!(<Option<T> as Decrypt>::reads_null(ty), "{ty:?}");
1536 }
1537 own::<i8>();
1538 own::<i16>();
1539 own::<i32>();
1540 own::<i64>();
1541 own::<i128>();
1542 own::<u16>();
1543 own::<u32>();
1544 own::<u64>();
1545 own::<u128>();
1546 own::<f32>();
1547 own::<f64>();
1548 assert!(!<String as Decrypt>::reads_null(plain(Width::U32)));
1550 assert!(!<Vec<u32> as Decrypt>::reads_null(plain(Width::U32)));
1551 assert!(!<bool as Decrypt>::reads_null(plain(Width::U8)));
1552 assert!(!<Option<String> as Decrypt>::reads_null(plain(Width::U32)));
1554 assert!(<Protected<u32> as Decrypt>::reads_null(plain(Width::U32)));
1555 assert!(!<Protected<String> as Decrypt>::reads_null(plain(
1556 Width::U32
1557 )));
1558 }
1559
1560 #[test]
1561 fn option_reads_null_and_undefined_as_none() {
1562 assert_eq!(round_trip::<Option<u32>>(None::<u32>).expect("none"), None);
1563 assert_eq!(
1564 round_trip::<Option<u32>>(Some(7u32)).expect("some"),
1565 Some(7)
1566 );
1567 assert_eq!(
1568 round_trip::<Option<u32>>(Raw(Some(Logical::Undefined), Physical::Null))
1569 .expect("undefined"),
1570 None
1571 );
1572 assert_eq!(
1573 round_trip::<Option<Vec<u32>>>(Some(vec![1u32])).expect("some seq"),
1574 Some(vec![1])
1575 );
1576 assert_eq!(
1577 round_trip::<Vec<Option<u32>>>(vec![Some(1u32), None]).expect("options"),
1578 [Some(1), None]
1579 );
1580 assert_eq!(expected(round_trip::<Option<u32>>("x")), "u32");
1581 }
1582
1583 #[test]
1584 fn a_typed_target_works_through_an_async_cipher() {
1585 let remote = Remote::new(true);
1586 let sealed = block_on(encrypt_async(vec![1u32, 2], &remote, ())).expect("encrypts");
1587 let out: Vec<u32> = block_on(decrypt_async(&remote, sealed, ())).expect("decrypts");
1588 assert_eq!(out, [1, 2]);
1589 assert_eq!(remote.calls(), 2);
1590 }
1591
1592 #[test]
1593 fn sync_and_async_decrypt_agree() {
1594 let mut value = BTreeMap::new();
1595 value.insert(String::from("a"), vec![Some(1u32), None]);
1596 value.insert(String::from("b"), vec![]);
1597 let sealed = || encrypt(value.clone(), &Mock, "ctx").expect("encrypts");
1599 let sync: BTreeMap<String, Vec<Option<u32>>> =
1600 decrypt(&Mock, sealed(), "ctx").expect("sync");
1601 let remote = Remote::new(true);
1602 let async_: BTreeMap<String, Vec<Option<u32>>> =
1603 block_on(decrypt_async(&remote, sealed(), "ctx")).expect("async");
1604 assert_eq!(sync, async_);
1605 assert_eq!(sync, value);
1606 }
1607
1608 #[test]
1609 fn maps_round_trip() {
1610 let mut hash = HashMap::new();
1611 hash.insert(String::from("a"), 1u32);
1612 hash.insert(String::from("b"), 2u32);
1613 assert_eq!(
1614 round_trip::<HashMap<String, u32>>(hash.clone()).expect("hash"),
1615 hash
1616 );
1617 let mut tree = BTreeMap::new();
1618 tree.insert("xs", vec![String::from("Ada")]);
1619 tree.insert("ys", vec![]);
1620 let back = round_trip::<BTreeMap<String, Vec<String>>>(tree).expect("tree");
1621 assert_eq!(back["xs"], ["Ada"]);
1622 assert!(back["ys"].is_empty());
1623 assert!(
1624 round_trip::<HashMap<String, u32>>(HashMap::<String, u32>::new())
1625 .expect("empty")
1626 .is_empty()
1627 );
1628 assert_eq!(
1629 expected(round_trip::<HashMap<String, u32>>(vec![1u32])),
1630 "map"
1631 );
1632 assert_eq!(expected(round_trip::<BTreeMap<String, u32>>(1u32)), "map");
1633 let mut bad = BTreeMap::new();
1635 bad.insert("a", "x");
1636 assert_eq!(expected(round_trip::<BTreeMap<String, u32>>(bad)), "u32");
1637 }
1638
1639 #[test]
1640 fn any_wipeable_scalar_reads_into_protected() {
1641 assert_eq!(
1642 *round_trip::<Protected<u64>>(34u64)
1643 .expect("u64")
1644 .risky_ref(),
1645 34
1646 );
1647 assert_eq!(
1648 round_trip::<Protected<[u8; 32]>>([7u8; 32])
1649 .expect("array")
1650 .risky_ref(),
1651 &[7; 32]
1652 );
1653 assert_eq!(
1654 expected(round_trip::<Protected<[u8; 4]>>(vec![1u8, 2])),
1655 "byte array"
1656 );
1657 assert_eq!(expected(round_trip::<Protected<u64>>("x")), "u64");
1658 }
1659
1660 #[test]
1661 fn a_scalar_target_refuses_a_map_and_a_passthrough() {
1662 let mut map = BTreeMap::new();
1663 map.insert("a", 1u32);
1664 assert_eq!(expected(round_trip::<u32>(map)), "u32");
1665
1666 #[derive(Clone)]
1669 struct Clear;
1670 impl Encrypt for Clear {
1671 fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1672 let mut seq = sink.seq(Some(2))?;
1673 seq.element()?.passthrough(7u16)?;
1674 8u16.visit(seq.element()?)?;
1675 seq.end()
1676 }
1677 }
1678 assert_eq!(expected(round_trip::<Vec<u16>>(Clear)), "u16");
1679 assert_eq!(expected(round_trip::<Vec<Option<u16>>>(Clear)), "u16");
1680 }
1681
1682 #[test]
1683 fn nested_maps_are_handed_up_to_their_container() {
1684 let mut row = BTreeMap::new();
1685 row.insert(String::from("a"), 1u32);
1686 let rows = vec![row.clone(), row.clone()];
1687 assert_eq!(
1688 round_trip::<Vec<BTreeMap<String, u32>>>(rows.clone()).expect("decodes"),
1689 rows
1690 );
1691 assert_eq!(
1692 round_trip::<Option<BTreeMap<String, u32>>>(Some(row.clone())).expect("decodes"),
1693 Some(row)
1694 );
1695 }
1696
1697 #[test]
1698 fn a_list_target_refuses_a_passthrough() {
1699 struct Clear;
1700 impl Encrypt for Clear {
1701 fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1702 sink.passthrough(vec![1u16])
1703 }
1704 }
1705 assert_eq!(expected(round_trip::<Vec<u16>>(Clear)), "sequence");
1706 }
1707
1708 #[test]
1709 fn f32_reads_only_an_f32() {
1710 assert_eq!(round_trip::<f32>(1.5f32).expect("decodes"), 1.5);
1711 assert_eq!(expected(round_trip::<f32>(1.5f64)), "f32");
1712 }
1713
1714 #[test]
1717 fn clear_decodes_a_passthrough_and_nothing_else() {
1718 let mut held = None;
1719 Clear::<Vec<u16>, _>::new(Slot(&mut held))
1720 .passthrough(vec![1u16, 2])
1721 .expect("decodes");
1722 assert_eq!(held, Some(vec![1, 2]));
1723 let refused = |r: Result<(), DecodeError>| {
1724 assert!(matches!(r, Err(DecodeError::Expected("passthrough"))))
1725 };
1726 let mut held: Option<u16> = None;
1727 refused(Clear::<u16, _>::new(Slot(&mut held)).scalar(None, Physical::Null));
1728 refused(Clear::<u16, _>::new(Slot(&mut held)).typed_null(plain(Width::U16)));
1729 refused(Clear::<u16, _>::new(Slot(&mut held)).seq(None).map(|_| ()));
1730 refused(Clear::<u16, _>::new(Slot(&mut held)).map(None).map(|_| ()));
1731 assert!(matches!(
1732 Clear::<u16, _>::new(Slot(&mut held)).passthrough("x"),
1733 Err(DecodeError::Expected("u16"))
1734 ));
1735 }
1736
1737 #[test]
1741 fn a_wrap_can_refuse_what_it_is_handed() {
1742 struct AtMostTwo;
1743 impl Rewrap<Vec<u16>> for AtMostTwo {
1744 type Output = Vec<u16>;
1745 fn rewrap(v: Vec<u16>) -> Result<Vec<u16>, DecodeError> {
1746 (v.len() <= 2)
1747 .then_some(v)
1748 .ok_or(DecodeError::Expected("at most two"))
1749 }
1750 }
1751 struct Even;
1752 impl Rewrap<u16> for Even {
1753 type Output = u16;
1754 fn rewrap(v: u16) -> Result<u16, DecodeError> {
1755 v.is_multiple_of(2)
1756 .then_some(v)
1757 .ok_or(DecodeError::Expected("even"))
1758 }
1759 }
1760 let short = vec![1u16, 2].visit(Wrapped::<_, AtMostTwo>::new(Vec::<u16>::sink()));
1761 assert_eq!(short.expect("two"), [1, 2]);
1762 let long = vec![1u16, 2, 3].visit(Wrapped::<_, AtMostTwo>::new(Vec::<u16>::sink()));
1763 assert!(matches!(long, Err(DecodeError::Expected("at most two"))));
1764 assert_eq!(
1765 4u16.visit(Wrapped::<_, Even>::new(u16::sink()))
1766 .expect("even"),
1767 4
1768 );
1769 assert!(matches!(
1770 5u16.visit(Wrapped::<_, Even>::new(u16::sink())),
1771 Err(DecodeError::Expected("even"))
1772 ));
1773 assert!(matches!(
1774 DecodeError::unknown_key("k"),
1775 DecodeError::UnknownKey(k) if k == "k"
1776 ));
1777 assert!(matches!(
1778 DecodeError::duplicate_key("k"),
1779 DecodeError::DuplicateKey(k) if k == "k"
1780 ));
1781 }
1782
1783 #[test]
1784 fn a_slot_holds_what_is_put() {
1785 let mut held = None;
1786 Slot(&mut held).put(3u8);
1787 assert_eq!(held, Some(3));
1788 }
1789
1790 #[test]
1791 fn some_none_reads_back_as_none() {
1792 assert_eq!(
1793 round_trip::<Option<Option<u32>>>(Some(None::<u32>)).expect("decodes"),
1794 None
1795 );
1796 assert_eq!(
1797 round_trip::<Option<Option<u32>>>(Some(Some(1u32))).expect("decodes"),
1798 Some(Some(1))
1799 );
1800 }
1801
1802 #[test]
1803 fn decode_errors_are_std_errors() {
1804 let e: Box<dyn core::error::Error> = Box::new(DecodeError::Expected("u32"));
1805 assert_eq!(e.to_string(), "expected u32");
1806 assert!(core::error::Error::source(&DecodeError::Expected("u32")).is_none());
1807 let source = DecodeError::Source(SourceError::new(core::fmt::Error));
1808 assert!(core::error::Error::source(&source).is_some());
1809 }
1810
1811 #[cfg(feature = "chrono")]
1812 #[test]
1813 fn chrono_targets_accept_any_unit() {
1814 use crate::plaintext::TimeUnit;
1815 use ::chrono::{DateTime, NaiveDate};
1816 let date = NaiveDate::from_ymd_opt(2024, 2, 29).expect("date");
1817 assert_eq!(round_trip::<NaiveDate>(date).expect("date"), date);
1818 let ts = DateTime::from_timestamp(1_700_000_000, 123_456_789).expect("ts");
1819 assert_eq!(round_trip::<DateTime<_>>(ts).expect("ts"), ts);
1820 let js = Raw(
1822 Some(Logical::Timestamp(TimeUnit::Millis)),
1823 Physical::Int(Int::I64(1_700_000_000_123)),
1824 );
1825 assert_eq!(
1826 round_trip::<DateTime<_>>(js).expect("ms"),
1827 DateTime::from_timestamp(1_700_000_000, 123_000_000).expect("ts")
1828 );
1829 assert_eq!(expected(round_trip::<NaiveDate>(0i32)), "date");
1830 }
1831
1832 #[cfg(feature = "rust_decimal")]
1833 #[test]
1834 fn decimal_round_trips_with_its_scale() {
1835 let d: rust_decimal::Decimal = "1.50".parse().expect("decimal");
1836 let back = round_trip::<rust_decimal::Decimal>(d).expect("decimal");
1837 assert_eq!(back, d);
1838 assert_eq!(back.scale(), 2);
1839 assert_eq!(
1840 expected(round_trip::<rust_decimal::Decimal>(150u32)),
1841 "decimal"
1842 );
1843 }
1844
1845 #[cfg(feature = "uuid")]
1846 #[test]
1847 fn uuid_round_trips() {
1848 let id = uuid::Uuid::from_bytes([5; 16]);
1849 assert_eq!(round_trip::<uuid::Uuid>(id).expect("uuid"), id);
1850 assert_eq!(expected(round_trip::<uuid::Uuid>(vec![5u8; 16])), "uuid");
1851 }
1852
1853 #[test]
1854 fn a_map_target_refuses_a_passthrough() {
1855 struct Clear;
1856 impl Encrypt for Clear {
1857 fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
1858 let mut map = BTreeMap::new();
1859 map.insert("a", 1u16);
1860 sink.passthrough(map)
1861 }
1862 }
1863 assert_eq!(expected(round_trip::<HashMap<String, u16>>(Clear)), "map");
1864 assert_eq!(expected(round_trip::<BTreeMap<String, u16>>(Clear)), "map");
1865 }
1866
1867 #[test]
1868 fn byte_targets_refuse_a_uuid_leaf() {
1869 let uuid = || Raw(Some(Logical::Uuid), Physical::Bytes(&[5; 16]));
1870 assert_eq!(expected(round_trip::<Vec<u8>>(uuid())), "bytes");
1871 assert_eq!(expected(round_trip::<[u8; 16]>(uuid())), "byte array");
1872 assert_eq!(
1873 expected(round_trip::<Protected<[u8; 16]>>(uuid())),
1874 "byte array"
1875 );
1876 }
1877
1878 #[cfg(feature = "chrono")]
1879 #[test]
1880 fn chrono_targets_refuse_the_other_logical_types() {
1881 use crate::plaintext::TimeUnit;
1882 use ::chrono::{DateTime, NaiveDate, Utc};
1883 let date = NaiveDate::from_ymd_opt(2024, 2, 29).expect("date");
1884 let ts = DateTime::from_timestamp(1_700_000_000, 0).expect("ts");
1885 assert_eq!(expected(round_trip::<DateTime<Utc>>(date)), "timestamp");
1886 assert_eq!(
1887 expected(round_trip::<DateTime<Utc>>(1_700_000_000i64)),
1888 "timestamp"
1889 );
1890 assert_eq!(expected(round_trip::<NaiveDate>(ts)), "date");
1891
1892 let instant = DateTime::from_timestamp(2, 0).expect("timestamp");
1893 for (unit, count) in [
1894 (TimeUnit::Seconds, 2),
1895 (TimeUnit::Millis, 2_000),
1896 (TimeUnit::Micros, 2_000_000),
1897 (TimeUnit::Nanos, 2_000_000_000),
1898 ] {
1899 let raw = Raw(
1900 Some(Logical::Timestamp(unit)),
1901 Physical::Int(Int::I64(count)),
1902 );
1903 assert_eq!(round_trip::<DateTime<Utc>>(raw).expect("unit"), instant);
1904 }
1905 }
1906
1907 #[test]
1908 fn a_wrong_aad_fails_before_the_target_is_checked() {
1909 let sealed = || encrypt(34u32, &Mock, "ctx").expect("encrypts");
1910 assert!(matches!(
1911 decrypt::<String, _, _>(&Mock, sealed(), "other"),
1912 Err(DecryptError::Cipher(_))
1913 ));
1914 assert!(matches!(
1915 decrypt::<Vec<u32>, _, _>(&Mock, sealed(), "other"),
1916 Err(DecryptError::Cipher(_))
1917 ));
1918 let remote = Remote::new(true);
1919 assert_eq!(
1922 block_on(decrypt_async::<u32, _, _>(&remote, sealed(), "ctx")).expect("decrypts"),
1923 34
1924 );
1925 assert!(matches!(
1926 block_on(decrypt_async::<String, _, _>(&remote, sealed(), "other")),
1927 Err(DecryptError::Cipher(_))
1928 ));
1929 }
1930
1931 #[test]
1932 fn a_null_is_refused_where_no_option_is_expected() {
1933 assert_eq!(expected(round_trip::<u32>(None::<u32>)), "u32");
1934 assert_eq!(expected(round_trip::<String>(None::<String>)), "string");
1935 assert_eq!(
1936 expected(round_trip::<Vec<u32>>(None::<Vec<u32>>)),
1937 "sequence"
1938 );
1939 assert_eq!(
1940 expected(round_trip::<Vec<u32>>(vec![Some(1u32), None])),
1941 "u32"
1942 );
1943 assert_eq!(
1944 expected(round_trip::<u32>(Raw(
1945 Some(Logical::Undefined),
1946 Physical::Null
1947 ))),
1948 "u32"
1949 );
1950 }
1951
1952 #[test]
1953 fn a_list_target_refuses_a_map() {
1954 let mut map = BTreeMap::new();
1955 map.insert("a", 1u32);
1956 assert_eq!(expected(round_trip::<Vec<u32>>(map)), "sequence");
1957 }
1958
1959 #[test]
1960 fn number_targets_refuse_the_other_number_kinds() {
1961 assert_eq!(expected(round_trip::<u32>(true)), "u32");
1962 assert_eq!(expected(round_trip::<i64>(1.0f64)), "i64");
1963 assert_eq!(expected(round_trip::<i64>(1.0f32)), "i64");
1964 assert_eq!(expected(round_trip::<f64>(1i64)), "f64");
1965 assert_eq!(expected(round_trip::<f32>(1u32)), "f32");
1966 }
1967
1968 #[test]
1969 fn integer_targets_accept_their_limits_and_nothing_past_them() {
1970 assert_eq!(round_trip::<i8>(i8::MIN).expect("i8"), i8::MIN);
1971 assert_eq!(round_trip::<i8>(127i32).expect("i8"), i8::MAX);
1972 assert_eq!(expected(round_trip::<i8>(-129i32)), "i8");
1973 assert_eq!(expected(round_trip::<i8>(128i32)), "i8");
1974 assert_eq!(round_trip::<u64>(u64::MAX).expect("u64"), u64::MAX);
1975 assert_eq!(expected(round_trip::<u64>(u128::from(u64::MAX) + 1)), "u64");
1976 assert_eq!(round_trip::<u128>(u128::MAX).expect("u128"), u128::MAX);
1977 assert_eq!(expected(round_trip::<u128>(-1i8)), "u128");
1978 assert_eq!(round_trip::<i128>(i128::MIN).expect("i128"), i128::MIN);
1979 assert_eq!(expected(round_trip::<i128>(u128::MAX)), "i128");
1980 }
1981
1982 #[test]
1983 fn a_source_error_displays_its_message() {
1984 assert_eq!(
1985 DecodeError::Source(SourceError::msg("getter threw")).to_string(),
1986 "source failed: getter threw"
1987 );
1988 assert_eq!(DecodeError::Expected("u32").to_string(), "expected u32");
1989 }
1990
1991 #[test]
1992 fn protected_containers_round_trip() {
1993 let ints = round_trip::<Protected<Vec<u32>>>(vec![1u32, 2, 3]).expect("decrypts");
1994 assert_eq!(ints.risky_ref(), &[1, 2, 3]);
1995 let some = round_trip::<Protected<Option<String>>>(Some("pw")).expect("decrypts");
1996 assert_eq!(some.risky_ref().as_deref(), Some("pw"));
1997 let none = round_trip::<Protected<Option<String>>>(None::<&str>).expect("decrypts");
1998 assert_eq!(none.risky_ref(), &None);
1999 let undefined =
2000 round_trip::<Protected<Option<u32>>>(Raw(Some(Logical::Undefined), Physical::Null))
2001 .expect("decrypts");
2002 assert_eq!(undefined.risky_ref(), &None);
2003 let nested = round_trip::<Protected<Vec<Vec<String>>>>(vec![vec!["a", "b"], vec![]])
2005 .expect("decrypts");
2006 assert_eq!(
2007 nested.risky_ref(),
2008 &[vec![String::from("a"), String::from("b")], vec![]]
2009 );
2010 let list = round_trip::<Protected<Option<Vec<u32>>>>(Some(vec![7u32])).expect("decrypts");
2011 assert_eq!(list.risky_ref(), &Some(vec![7]));
2012 let arrays = round_trip::<Protected<Vec<Option<[u8; 2]>>>>(vec![Some([1u8, 2]), None])
2013 .expect("decrypts");
2014 assert_eq!(arrays.risky_ref(), &[Some([1, 2]), None]);
2015 let bytes = round_trip::<Protected<Vec<u8>>>(vec![9u8, 8]).expect("decrypts");
2017 assert_eq!(bytes.risky_ref(), &[9, 8]);
2018 }
2019
2020 #[test]
2021 fn protected_containers_refuse_what_their_bare_forms_refuse() {
2022 let mut map = BTreeMap::new();
2023 map.insert("a", 1u32);
2024 assert_eq!(expected(round_trip::<Protected<Vec<u32>>>(map)), "sequence");
2025 assert_eq!(
2026 expected(round_trip::<Protected<Vec<u32>>>(1u32)),
2027 "sequence"
2028 );
2029 assert_eq!(
2030 expected(round_trip::<Protected<Vec<u32>>>(vec!["x"])),
2031 "u32"
2032 );
2033 assert_eq!(expected(round_trip::<Protected<Option<u32>>>("x")), "u32");
2034 assert_eq!(
2035 expected(round_trip::<Protected<Option<Vec<u32>>>>(1u32)),
2036 "sequence"
2037 );
2038 struct Clear;
2039 impl Encrypt for Clear {
2040 fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
2041 sink.passthrough(vec![1u32])
2042 }
2043 }
2044 assert_eq!(
2045 expected(round_trip::<Protected<Vec<u32>>>(Clear)),
2046 "sequence"
2047 );
2048 assert_eq!(expected(round_trip::<Protected<Option<u32>>>(Clear)), "u32");
2049 assert_eq!(expected(round_trip::<Protected<u32>>(Clear)), "u32");
2050 assert_eq!(expected(round_trip::<Protected<u32>>(vec![1u32])), "u32");
2051 let mut map = BTreeMap::new();
2052 map.insert("a", 1u32);
2053 assert_eq!(expected(round_trip::<Protected<u32>>(map)), "u32");
2054 }
2055
2056 std::thread_local! {
2057 static WIPES: core::cell::Cell<usize> = const { core::cell::Cell::new(0) };
2058 }
2059
2060 struct Wiped(u32);
2062
2063 impl Zeroize for Wiped {
2064 fn zeroize(&mut self) {
2065 self.0 = 0;
2066 WIPES.with(|w| w.set(w.get() + 1));
2067 }
2068 }
2069
2070 impl FromScalar for Wiped {
2071 const EXPECTED: &'static str = "wiped";
2072 fn from_scalar(ty: Option<Logical>, v: Physical<'_>) -> Option<Self> {
2073 u32::from_scalar(ty, v).map(Wiped)
2074 }
2075 }
2076
2077 #[test]
2078 fn a_protected_list_that_fails_part_way_wipes_what_it_decoded() {
2079 let source = vec![
2080 Raw(None, Physical::Int(Int::U32(1))),
2081 Raw(None, Physical::Int(Int::U32(2))),
2082 Raw(None, Physical::Text("x")),
2083 ];
2084 WIPES.with(|w| w.set(0));
2085 let result = round_trip::<Protected<Vec<Wiped>>>(source);
2086 assert_eq!(expected(result), "wiped");
2087 assert_eq!(WIPES.with(|w| w.get()), 2);
2088 }
2089
2090 struct Unsized(u32);
2092
2093 impl Encrypt for Unsized {
2094 fn visit<S: Sink>(self, sink: S) -> Result<S::Ok, S::Error> {
2095 let mut seq = sink.seq(None)?;
2096 for i in 0..self.0 {
2097 i.visit(seq.element()?)?;
2098 }
2099 seq.end()
2100 }
2101 }
2102
2103 #[test]
2104 fn a_protected_list_grows_by_doubling_into_a_fresh_buffer() {
2105 let decode = |n| {
2106 Unsized(n)
2107 .visit(<Protected<Vec<u32>> as Decrypt>::sink())
2108 .expect("decodes")
2109 };
2110 let five = decode(5);
2111 assert_eq!(five.risky_ref(), &[0, 1, 2, 3, 4]);
2112 assert_eq!(five.risky_ref().capacity(), 8);
2113 let nine = decode(9);
2114 assert_eq!(nine.risky_ref(), &(0..9).collect::<Vec<_>>());
2115 assert_eq!(nine.risky_ref().capacity(), 16);
2116 }
2117
2118 #[derive(Debug, PartialEq)]
2121 struct Point {
2122 x: u32,
2123 }
2124
2125 impl Zeroize for Point {
2126 fn zeroize(&mut self) {
2127 self.x.zeroize();
2128 }
2129 }
2130
2131 struct PointSink;
2132 struct PointFields(Option<u32>);
2133
2134 impl Sink for PointSink {
2135 type Ok = Point;
2136 type Error = DecodeError;
2137 type Seq = Never<Point>;
2138 type Map = PointFields;
2139
2140 fn scalar(self, _: Option<Logical>, _: Physical<'_>) -> Result<Point, DecodeError> {
2141 Err(DecodeError::Expected("point"))
2142 }
2143
2144 fn typed_null(self, _: FixedType) -> Result<Point, DecodeError> {
2145 Err(DecodeError::Expected("point"))
2146 }
2147
2148 fn seq(self, _: Option<usize>) -> Result<Never<Point>, DecodeError> {
2149 Err(DecodeError::Expected("point"))
2150 }
2151
2152 fn map(self, _: Option<usize>) -> Result<PointFields, DecodeError> {
2153 Ok(PointFields(None))
2154 }
2155
2156 fn passthrough<P: Encrypt + Clone>(self, _: P) -> Result<Point, DecodeError> {
2157 Err(DecodeError::Expected("point"))
2158 }
2159 }
2160
2161 impl MapSink for PointFields {
2162 type Ok = Point;
2163 type Error = DecodeError;
2164 type Entry<'s> = Forward<u32, Slot<'s, u32>>;
2165
2166 fn entry(&mut self, key: &str) -> Result<Self::Entry<'_>, DecodeError> {
2167 match key {
2168 "x" => Ok(Forward(u32::sink(), Slot(&mut self.0))),
2169 _ => Err(DecodeError::Expected("point")),
2170 }
2171 }
2172
2173 fn end(self) -> Result<Point, DecodeError> {
2174 self.0
2175 .map(|x| Point { x })
2176 .ok_or(DecodeError::Expected("point"))
2177 }
2178 }
2179
2180 impl Decrypt for Point {
2181 type Sink = PointSink;
2182 fn sink() -> PointSink {
2183 PointSink
2184 }
2185 }
2186
2187 impl DecryptProtected for Point {
2188 type ProtectedSink = Wrap<PointSink>;
2189 fn protected_sink() -> Wrap<PointSink> {
2190 Wrap(PointSink)
2191 }
2192 }
2193
2194 #[test]
2195 fn a_struct_target_opts_into_protected_through_wrap() {
2196 let point = || {
2197 let mut map = BTreeMap::new();
2198 map.insert("x", 3u32);
2199 map
2200 };
2201 let p = round_trip::<Protected<Point>>(point()).expect("decrypts");
2202 assert_eq!(p.risky_ref(), &Point { x: 3 });
2203 let some = round_trip::<Protected<Option<Point>>>(Some(point())).expect("decrypts");
2204 assert_eq!(some.risky_ref(), &Some(Point { x: 3 }));
2205 let list = round_trip::<Protected<Vec<Point>>>(vec![point()]).expect("decrypts");
2206 assert_eq!(list.risky_ref(), &[Point { x: 3 }]);
2207 assert_eq!(expected(round_trip::<Protected<Point>>(1u32)), "point");
2208 assert_eq!(
2209 expected(round_trip::<Protected<Point>>(vec![1u32])),
2210 "point"
2211 );
2212 let mut extra = point();
2213 extra.insert("y", 4u32);
2214 assert_eq!(expected(round_trip::<Protected<Point>>(extra)), "point");
2215 }
2216
2217 #[test]
2218 fn wrap_moves_any_sink_result_into_protected() {
2219 let n = Wrap(u32::sink())
2220 .scalar(None, Physical::Int(Int::U32(5)))
2221 .expect("decodes");
2222 assert_eq!(n.risky_ref(), &5);
2223 assert!(matches!(
2224 Wrap(u32::sink()).passthrough(5u32),
2225 Err(DecodeError::Expected("u32"))
2226 ));
2227 let list = vec![1u32, 2]
2228 .visit(Wrap(<Vec<u32>>::sink()))
2229 .expect("decodes");
2230 assert_eq!(list.risky_ref(), &[1, 2]);
2231 }
2232}