1use crate::buf::ReverseBuf;
2use crate::encoding::{
3 Capped, DecodeContext, DistinguishedValueBorrowDecoder, DistinguishedValueDecoder,
4 ForOverwrite, RestrictedDecodeContext, ValueBorrowDecoder, ValueDecoder, ValueEncoder,
5 WireType, Wiretyped,
6};
7use crate::{Canonicity, DecodeError, DecodeErrorKind};
8use bytes::{Buf, BufMut};
9use core::ops::Deref;
10
11pub struct Proxied<E, Tag = ()>(E, Tag);
22
23pub(crate) struct SealedBilrostTag;
26
27pub trait Proxiable<Tag = ()> {
32 type Proxy;
34
35 fn encode_proxy(&self) -> Self::Proxy;
37
38 fn decode_proxy(&mut self, proxy: Self::Proxy) -> Result<(), DecodeErrorKind>;
42}
43
44pub trait DistinguishedProxiable<Tag = ()>: Proxiable<Tag> {
46 fn decode_proxy_distinguished(
52 &mut self,
53 proxy: Self::Proxy,
54 ) -> Result<Canonicity, DecodeErrorKind>;
55}
56
57impl<T, E, Tag> Wiretyped<Proxied<E, Tag>, T> for ()
58where
59 T: Proxiable<Tag>,
60 (): Wiretyped<E, T::Proxy> + ForOverwrite<E, T::Proxy>,
61{
62 const WIRE_TYPE: WireType = <() as Wiretyped<E, T::Proxy>>::WIRE_TYPE;
63}
64
65impl<T, E, Tag> ValueEncoder<Proxied<E, Tag>, T> for ()
66where
67 T: Proxiable<Tag>,
68 (): ForOverwrite<E, T::Proxy> + ValueEncoder<E, T::Proxy>,
69{
70 #[inline]
71 fn encode_value<B: BufMut + ?Sized>(value: &T, buf: &mut B) {
72 <() as ValueEncoder<E, _>>::encode_value(&value.encode_proxy(), buf);
73 }
74
75 #[inline]
76 fn prepend_value<B: ReverseBuf + ?Sized>(value: &T, buf: &mut B) {
77 <() as ValueEncoder<E, _>>::prepend_value(&value.encode_proxy(), buf);
78 }
79
80 #[inline]
81 fn value_encoded_len(value: &T) -> usize {
82 <() as ValueEncoder<E, _>>::value_encoded_len(&value.encode_proxy())
83 }
84
85 #[inline]
86 fn many_values_encoded_len<I>(values: I) -> usize
87 where
88 I: ExactSizeIterator,
89 I::Item: Deref<Target = T>,
90 {
91 #[repr(transparent)]
94 struct WrapDeref<T>(T);
95
96 impl<T> Deref for WrapDeref<T> {
97 type Target = T;
98
99 fn deref(&self) -> &Self::Target {
100 &self.0
101 }
102 }
103
104 <() as ValueEncoder<E, _>>::many_values_encoded_len(
105 values.map(|item| WrapDeref(item.encode_proxy())),
106 )
107 }
108}
109
110impl<T, E, Tag> ValueDecoder<Proxied<E, Tag>, T> for ()
111where
112 T: Proxiable<Tag>,
113 (): ForOverwrite<E, T::Proxy> + ValueDecoder<E, T::Proxy>,
114{
115 #[inline]
116 fn decode_value<B: Buf + ?Sized>(
117 value: &mut T,
118 buf: Capped<B>,
119 ctx: DecodeContext,
120 ) -> Result<(), DecodeError> {
121 let mut proxy = <() as ForOverwrite<E, T::Proxy>>::for_overwrite();
122 <() as ValueDecoder<E, _>>::decode_value(&mut proxy, buf, ctx)?;
123 Ok(value.decode_proxy(proxy)?)
124 }
125}
126
127impl<T, E, Tag> DistinguishedValueDecoder<Proxied<E, Tag>, T> for ()
128where
129 T: DistinguishedProxiable<Tag> + Eq,
130 (): ForOverwrite<E, T::Proxy> + DistinguishedValueDecoder<E, T::Proxy>,
131{
132 const CHECKS_EMPTY: bool = <() as DistinguishedValueDecoder<E, T::Proxy>>::CHECKS_EMPTY;
133
134 fn decode_value_distinguished<const ALLOW_EMPTY: bool>(
135 value: &mut T,
136 buf: Capped<impl Buf + ?Sized>,
137 ctx: RestrictedDecodeContext,
138 ) -> Result<Canonicity, DecodeError> {
139 let mut proxy = <() as ForOverwrite<E, T::Proxy>>::for_overwrite();
140 let mut canon = <() as DistinguishedValueDecoder<E, _>>::decode_value_distinguished::<
141 ALLOW_EMPTY,
142 >(&mut proxy, buf, ctx.clone())?;
143 canon.update(ctx.check(value.decode_proxy_distinguished(proxy)?)?);
144 Ok(canon)
145 }
146}
147
148impl<'a, T, E, Tag> ValueBorrowDecoder<'a, Proxied<E, Tag>, T> for ()
149where
150 T: Proxiable<Tag>,
151 (): ForOverwrite<E, T::Proxy> + ValueBorrowDecoder<'a, E, T::Proxy>,
152{
153 #[inline]
154 fn borrow_decode_value(
155 value: &mut T,
156 buf: Capped<&'a [u8]>,
157 ctx: DecodeContext,
158 ) -> Result<(), DecodeError> {
159 let mut proxy = <() as ForOverwrite<E, T::Proxy>>::for_overwrite();
160 <() as ValueBorrowDecoder<E, _>>::borrow_decode_value(&mut proxy, buf, ctx)?;
161 Ok(value.decode_proxy(proxy)?)
162 }
163}
164
165impl<'a, T, E, Tag> DistinguishedValueBorrowDecoder<'a, Proxied<E, Tag>, T> for ()
166where
167 T: DistinguishedProxiable<Tag> + Eq,
168 (): ForOverwrite<E, T::Proxy> + DistinguishedValueBorrowDecoder<'a, E, T::Proxy>,
169{
170 const CHECKS_EMPTY: bool = <() as DistinguishedValueBorrowDecoder<E, T::Proxy>>::CHECKS_EMPTY;
171
172 fn borrow_decode_value_distinguished<const ALLOW_EMPTY: bool>(
173 value: &mut T,
174 buf: Capped<&'a [u8]>,
175 ctx: RestrictedDecodeContext,
176 ) -> Result<Canonicity, DecodeError> {
177 let mut proxy = <() as ForOverwrite<E, T::Proxy>>::for_overwrite();
178 let mut canon =
179 <() as DistinguishedValueBorrowDecoder<E, _>>::borrow_decode_value_distinguished::<
180 ALLOW_EMPTY,
181 >(&mut proxy, buf, ctx.clone())?;
182 canon.update(ctx.check(value.decode_proxy_distinguished(proxy)?)?);
183 Ok(canon)
184 }
185}