1use nodecraft::CheapClone;
2
3use super::{
4 Data, DataRef, DecodeError, EncodeError,
5 utils::{merge, skip},
6};
7
8#[derive(
10 Clone,
11 Copy,
12 Debug,
13 PartialEq,
14 Eq,
15 Hash,
16 derive_more::Display,
17 derive_more::TryUnwrap,
18 derive_more::Unwrap,
19 derive_more::IsVariant,
20)]
21#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
24#[unwrap(ref, ref_mut)]
25#[try_unwrap(ref, ref_mut)]
26pub enum MaybeResolvedAddress<A, R> {
27 #[display("{_0}")]
29 Resolved(R),
30 #[display("{_0}")]
32 Unresolved(A),
33}
34
35impl<A: CheapClone, R: CheapClone> CheapClone for MaybeResolvedAddress<A, R> {
36 fn cheap_clone(&self) -> Self {
37 match self {
38 Self::Resolved(addr) => Self::Resolved(addr.cheap_clone()),
39 Self::Unresolved(addr) => Self::Unresolved(addr.cheap_clone()),
40 }
41 }
42}
43
44impl<A, R> MaybeResolvedAddress<A, R> {
45 #[inline]
47 pub const fn resolved(addr: R) -> Self {
48 Self::Resolved(addr)
49 }
50
51 #[inline]
53 pub const fn unresolved(addr: A) -> Self {
54 Self::Unresolved(addr)
55 }
56
57 #[inline]
59 pub const fn as_ref(&self) -> MaybeResolvedAddress<&A, &R> {
60 match self {
61 Self::Resolved(addr) => MaybeResolvedAddress::Resolved(addr),
62 Self::Unresolved(addr) => MaybeResolvedAddress::Unresolved(addr),
63 }
64 }
65
66 #[inline]
68 pub const fn as_mut(&mut self) -> MaybeResolvedAddress<&mut A, &mut R> {
69 match self {
70 Self::Resolved(addr) => MaybeResolvedAddress::Resolved(addr),
71 Self::Unresolved(addr) => MaybeResolvedAddress::Unresolved(addr),
72 }
73 }
74}
75
76const RESOLVED_TAG: u8 = 1;
77const UNRESOLVED_TAG: u8 = 2;
78
79impl<A, R> MaybeResolvedAddress<A, R>
80where
81 A: Data,
82 R: Data,
83{
84 #[inline]
85 const fn resolved_byte() -> u8 {
86 merge(R::WIRE_TYPE, RESOLVED_TAG)
87 }
88
89 #[inline]
90 const fn unresolved_byte() -> u8 {
91 merge(A::WIRE_TYPE, UNRESOLVED_TAG)
92 }
93}
94
95impl<'a, A, R> DataRef<'a, MaybeResolvedAddress<A, R>>
96 for MaybeResolvedAddress<A::Ref<'a>, R::Ref<'a>>
97where
98 A: Data,
99 R: Data,
100{
101 fn decode(buf: &'a [u8]) -> Result<(usize, Self), DecodeError>
102 where
103 Self: Sized,
104 {
105 let mut offset = 0;
106 let buf_len = buf.len();
107 let mut addr = None;
108
109 while offset < buf_len {
110 match buf[offset] {
111 byte if byte == MaybeResolvedAddress::<A, R>::resolved_byte() => {
112 if addr.is_some() {
113 return Err(DecodeError::duplicate_field(
114 "MaybeResolvedAddress",
115 "value",
116 RESOLVED_TAG,
117 ));
118 }
119
120 offset += 1;
121
122 let (len, val) = <R::Ref<'_> as DataRef<'_, R>>::decode_length_delimited(&buf[offset..])?;
123 offset += len;
124 addr = Some(Self::Resolved(val));
125 }
126 byte if byte == MaybeResolvedAddress::<A, R>::unresolved_byte() => {
127 if addr.is_some() {
128 return Err(DecodeError::duplicate_field(
129 "MaybeResolvedAddress",
130 "value",
131 UNRESOLVED_TAG,
132 ));
133 }
134 offset += 1;
135
136 let (len, val) = <A::Ref<'_> as DataRef<'_, A>>::decode_length_delimited(&buf[offset..])?;
137 offset += len;
138 addr = Some(Self::Unresolved(val));
139 }
140 _ => offset += skip("MaybeResolvedAddress", &buf[offset..])?,
141 }
142 }
143
144 let addr = addr.ok_or_else(|| DecodeError::missing_field("MaybeResolvedAddress", "value"))?;
145 Ok((offset, addr))
146 }
147}
148
149impl<A, R> Data for MaybeResolvedAddress<A, R>
150where
151 A: Data,
152 R: Data,
153{
154 type Ref<'a> = MaybeResolvedAddress<A::Ref<'a>, R::Ref<'a>>;
155
156 fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError>
157 where
158 Self: Sized,
159 {
160 match val {
161 MaybeResolvedAddress::Resolved(addr) => R::from_ref(addr).map(Self::Resolved),
162 MaybeResolvedAddress::Unresolved(addr) => A::from_ref(addr).map(Self::Unresolved),
163 }
164 }
165
166 fn encoded_len(&self) -> usize {
167 1 + match self {
168 Self::Resolved(addr) => addr.encoded_len_with_length_delimited(),
169 Self::Unresolved(addr) => addr.encoded_len_with_length_delimited(),
170 }
171 }
172
173 fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
174 let mut offset = 0;
175 let buf_len = buf.len();
176 match self {
177 Self::Resolved(addr) => {
178 if buf_len < 1 {
179 return Err(EncodeError::insufficient_buffer(
180 self.encoded_len(),
181 buf_len,
182 ));
183 }
184
185 buf[offset] = Self::resolved_byte();
186 offset += 1;
187 offset += addr.encode_length_delimited(&mut buf[offset..])?;
188 }
189 Self::Unresolved(addr) => {
190 if buf_len < 1 {
191 return Err(EncodeError::insufficient_buffer(
192 self.encoded_len(),
193 buf_len,
194 ));
195 }
196
197 buf[offset] = Self::unresolved_byte();
198 offset += 1;
199 offset += addr.encode_length_delimited(&mut buf[offset..])?;
200 }
201 }
202
203 #[cfg(debug_assertions)]
204 super::debug_assert_write_eq::<Self>(offset, self.encoded_len());
205
206 Ok(offset)
207 }
208}