1use compact_u64::*;
2use ufotofu::{ConsumeAtLeastError, codec_prelude::*};
3
4use super::*;
5
6async fn encode_from_iterator_of_components<'a, const MCL: usize, C, I>(
8 consumer: &mut C,
9 path_length: u64,
10 component_count: u64,
11 components: I,
12) -> Result<(), C::Error>
13where
14 C: BulkConsumer<Item = u8> + ?Sized,
15 I: Iterator<Item = &'a Component<MCL>>,
16{
17 let mut header = 0;
21 write_tag(&mut header, 4, 0, path_length);
22 write_tag(&mut header, 4, 4, component_count);
23 consumer.consume_item(header).await?;
24
25 cu64_encode(path_length, 4, consumer).await?;
27
28 cu64_encode(component_count, 4, consumer).await?;
30
31 for (i, component) in components.enumerate() {
33 if i as u64 + 1 != component_count {
35 cu64_encode_standalone(component.len() as u64, consumer).await?;
36 }
37
38 consumer
40 .bulk_consume_full_slice(component.as_ref())
41 .await
42 .map_err(ConsumeAtLeastError::into_reason)?;
43 }
44
45 Ok(())
46}
47
48impl<const MCL: usize, const MCC: usize, const MPL: usize> Encodable for Path<MCL, MCC, MPL> {
50 async fn encode<C>(&self, consumer: &mut C) -> Result<(), C::Error>
51 where
52 C: BulkConsumer<Item = u8> + ?Sized,
53 {
54 encode_from_iterator_of_components::<MCL, _, _>(
55 consumer,
56 self.total_length() as u64,
57 self.component_count() as u64,
58 self.components(),
59 )
60 .await
61 }
62}
63
64async fn decode_total_length_and_component_count_maybe_canonic<const CANONIC: bool, P>(
67 producer: &mut P,
68) -> Result<(usize, usize), DecodeError<P::Final, P::Error, Blame>>
69where
70 P: BulkProducer<Item = u8> + ?Sized,
71{
72 let header = producer.produce_item().await?;
74
75 let total_length = if CANONIC {
77 cu64_decode_canonic(header, 4, 0, producer)
78 .await
79 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
80 } else {
81 cu64_decode(header, 4, 0, producer)
82 .await
83 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
84 };
85
86 let component_count = if CANONIC {
87 cu64_decode_canonic(header, 4, 4, producer)
88 .await
89 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
90 } else {
91 cu64_decode(header, 4, 4, producer)
92 .await
93 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
94 };
95
96 let total_length = Blame::u64_to_usize(total_length)?;
98 let component_count = Blame::u64_to_usize(component_count)?;
99
100 Ok((total_length, component_count))
101}
102
103async fn decode_components_maybe_canonic<
106 const CANONIC: bool,
107 const MCL: usize,
108 const MCC: usize,
109 const MPL: usize,
110 P,
111>(
112 producer: &mut P,
113 mut builder: PathBuilder<MCL, MCC, MPL>,
114 initial_accumulated_component_length: usize,
115 remaining_component_count: usize,
116 expected_total_length: usize,
117) -> Result<Path<MCL, MCC, MPL>, DecodeError<P::Final, P::Error, Blame>>
118where
119 P: BulkProducer<Item = u8> + ?Sized,
120{
121 let mut accumulated_component_length = initial_accumulated_component_length;
124
125 if remaining_component_count == 0 {
127 if expected_total_length > accumulated_component_length {
128 Err(DecodeError::Other(Blame::TheirFault))
130 } else {
131 Ok(builder.build())
133 }
134 } else {
135 for _ in 1..remaining_component_count {
139 let component_len = Blame::u64_to_usize(if CANONIC {
140 cu64_decode_canonic_standalone(producer)
141 .await
142 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
143 } else {
144 cu64_decode_standalone(producer)
145 .await
146 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
147 })?;
148
149 if component_len > MCL {
150 return Err(DecodeError::Other(Blame::TheirFault));
152 } else {
153 accumulated_component_length = accumulated_component_length
155 .checked_add(component_len)
156 .ok_or(DecodeError::Other(Blame::TheirFault))?;
157
158 builder
160 .append_component_from_bulk_producer(component_len, producer)
161 .await?;
162 }
163 }
164
165 let final_component_length = expected_total_length
167 .checked_sub(accumulated_component_length)
168 .ok_or(DecodeError::Other(Blame::TheirFault))?;
169
170 if final_component_length > MCL {
171 Err(DecodeError::Other(Blame::TheirFault))
173 } else {
174 builder
176 .append_component_from_bulk_producer(final_component_length, producer)
177 .await?;
178
179 Ok(builder.build())
181 }
182 }
183}
184
185async fn decode_maybe_canonic<
187 const CANONIC: bool,
188 const MCL: usize,
189 const MCC: usize,
190 const MPL: usize,
191 P,
192>(
193 producer: &mut P,
194) -> Result<Path<MCL, MCC, MPL>, DecodeError<P::Final, P::Error, Blame>>
195where
196 P: BulkProducer<Item = u8> + ?Sized,
197{
198 let (total_length, component_count) =
199 decode_total_length_and_component_count_maybe_canonic::<CANONIC, _>(producer).await?;
200
201 let builder = PathBuilder::new(total_length, component_count)
203 .map_err(|_| DecodeError::Other(Blame::TheirFault))?;
204
205 decode_components_maybe_canonic::<CANONIC, MCL, MCC, MPL, _>(
206 producer,
207 builder,
208 0,
209 component_count,
210 total_length,
211 )
212 .await
213}
214
215impl<const MCL: usize, const MCC: usize, const MPL: usize> Decodable for Path<MCL, MCC, MPL> {
217 type ErrorReason = Blame;
218
219 async fn decode<P>(
220 producer: &mut P,
221 ) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>
222 where
223 P: BulkProducer<Item = u8> + ?Sized,
224 {
225 decode_maybe_canonic::<false, MCL, MCC, MPL, _>(producer).await
226 }
227}
228
229impl<const MCL: usize, const MCC: usize, const MPL: usize> DecodableCanonic
231 for Path<MCL, MCC, MPL>
232{
233 type ErrorCanonic = Blame;
234
235 async fn decode_canonic<P>(
236 producer: &mut P,
237 ) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorCanonic>>
238 where
239 P: BulkProducer<Item = u8> + ?Sized,
240 {
241 decode_maybe_canonic::<true, MCL, MCC, MPL, _>(producer).await
242 }
243}
244
245fn encoding_len_from_iterator_of_components<'a, const MCL: usize, I>(
247 path_length: u64,
248 component_count: usize,
249 components: I,
250) -> usize
251where
252 I: Iterator<Item = &'a Component<MCL>>,
253{
254 let mut total_enc_len = 1; total_enc_len += cu64_len_of_encoding(4, path_length);
257 total_enc_len += cu64_len_of_encoding(4, component_count as u64);
258
259 for (i, comp) in components.enumerate() {
260 if i + 1 < component_count {
261 total_enc_len += cu64_len_of_encoding(8, comp.len() as u64) + 1;
262 }
263
264 total_enc_len += comp.len();
265 }
266
267 total_enc_len
268}
269
270impl<const MCL: usize, const MCC: usize, const MPL: usize> EncodableKnownLength
272 for Path<MCL, MCC, MPL>
273{
274 fn len_of_encoding(&self) -> usize {
275 encoding_len_from_iterator_of_components::<MCL, _>(
276 self.total_length() as u64,
277 self.component_count(),
278 self.components(),
279 )
280 }
281}
282
283impl<const MCL: usize, const MCC: usize, const MPL: usize> RelativeEncodable<Path<MCL, MCC, MPL>>
289 for Path<MCL, MCC, MPL>
290{
291 async fn relative_encode<Consumer>(
292 &self,
293 rel: &Path<MCL, MCC, MPL>,
294 consumer: &mut Consumer,
295 ) -> Result<(), Consumer::Error>
296 where
297 Consumer: BulkConsumer<Item = u8> + ?Sized,
298 {
299 let lcp = self.longest_common_prefix(rel);
300
301 cu64_encode_standalone(lcp.component_count() as u64, consumer).await?;
302
303 let suffix_length = self.total_length() - lcp.total_length();
304 let suffix_component_count = self.component_count() - lcp.component_count();
305
306 encode_from_iterator_of_components::<MCL, _, _>(
307 consumer,
308 suffix_length as u64,
309 suffix_component_count as u64,
310 self.suffix_components(lcp.component_count()),
311 )
312 .await
313 }
314
315 fn can_be_encoded_relative_to(&self, _rel: &Path<MCL, MCC, MPL>) -> bool {
317 true
318 }
319}
320
321async fn relative_decode_maybe_canonic<
323 const CANONIC: bool,
324 const MCL: usize,
325 const MCC: usize,
326 const MPL: usize,
327 P,
328>(
329 producer: &mut P,
330 rel: &Path<MCL, MCC, MPL>,
331) -> Result<Path<MCL, MCC, MPL>, DecodeError<P::Final, P::Error, Blame>>
332where
333 P: BulkProducer<Item = u8> + ?Sized,
334{
335 let prefix_component_count = Blame::u64_to_usize(if CANONIC {
336 cu64_decode_canonic_standalone(producer)
337 .await
338 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
339 } else {
340 cu64_decode_standalone(producer)
341 .await
342 .map_err(|err| err.map_other(|_| Blame::TheirFault))?
343 })?;
344
345 let (suffix_length, suffix_component_count) =
346 decode_total_length_and_component_count_maybe_canonic::<CANONIC, _>(producer).await?;
347
348 if prefix_component_count > rel.component_count() {
349 return Err(DecodeError::Other(Blame::TheirFault));
350 }
351
352 let prefix_path_length = rel.total_length_of_prefix(prefix_component_count);
353
354 let total_length = prefix_path_length
355 .checked_add(suffix_length)
356 .ok_or(DecodeError::Other(Blame::TheirFault))?;
357 let total_component_count = prefix_component_count
358 .checked_add(suffix_component_count)
359 .ok_or(DecodeError::Other(Blame::TheirFault))?;
360
361 let builder = PathBuilder::new_from_prefix(
363 total_length,
364 total_component_count,
365 rel,
366 prefix_component_count,
367 )
368 .map_err(|_| DecodeError::Other(Blame::TheirFault))?;
369
370 let decoded = decode_components_maybe_canonic::<CANONIC, MCL, MCC, MPL, _>(
372 producer,
373 builder,
374 prefix_path_length,
375 suffix_component_count,
376 total_length,
377 )
378 .await?;
379
380 if CANONIC {
381 if prefix_component_count == rel.component_count() {
383 Ok(decoded)
385 } else if prefix_component_count == decoded.component_count() {
386 Ok(decoded)
388 } else {
389 if rel.component(prefix_component_count).unwrap()
393 == decoded.component(prefix_component_count).unwrap()
394 {
395 Err(DecodeError::Other(Blame::TheirFault))
397 } else {
398 Ok(decoded)
400 }
401 }
402 } else {
403 Ok(decoded)
405 }
406}
407
408impl<const MCL: usize, const MCC: usize, const MPL: usize> RelativeDecodable<Path<MCL, MCC, MPL>>
410 for Path<MCL, MCC, MPL>
411{
412 type ErrorReason = Blame;
413
414 async fn relative_decode<P>(
415 rel: &Path<MCL, MCC, MPL>,
416 producer: &mut P,
417 ) -> Result<Self, DecodeError<P::Final, P::Error, Blame>>
418 where
419 P: BulkProducer<Item = u8> + ?Sized,
420 {
421 relative_decode_maybe_canonic::<false, MCL, MCC, MPL, _>(producer, rel).await
422 }
423}
424
425impl<const MCL: usize, const MCC: usize, const MPL: usize>
427 RelativeDecodableCanonic<Path<MCL, MCC, MPL>> for Path<MCL, MCC, MPL>
428{
429 type ErrorCanonic = Blame;
430
431 async fn relative_decode_canonic<P>(
432 rel: &Path<MCL, MCC, MPL>,
433 producer: &mut P,
434 ) -> Result<Self, DecodeError<P::Final, P::Error, Blame>>
435 where
436 P: BulkProducer<Item = u8> + ?Sized,
437 {
438 relative_decode_maybe_canonic::<true, MCL, MCC, MPL, _>(producer, rel).await
439 }
440}
441
442impl<const MCL: usize, const MCC: usize, const MPL: usize>
444 RelativeEncodableKnownLength<Path<MCL, MCC, MPL>> for Path<MCL, MCC, MPL>
445{
446 fn len_of_relative_encoding(&self, rel: &Path<MCL, MCC, MPL>) -> usize {
447 let lcp = self.longest_common_prefix(rel);
448 let path_len_of_suffix = self.total_length() - lcp.total_length();
449 let component_count_of_suffix = self.component_count() - lcp.component_count();
450
451 let mut total_enc_len = 0;
452
453 total_enc_len += cu64_len_of_encoding(8, lcp.component_count() as u64) + 1;
455
456 total_enc_len += encoding_len_from_iterator_of_components::<MCL, _>(
457 path_len_of_suffix as u64,
458 component_count_of_suffix,
459 self.suffix_components(lcp.component_count()),
460 );
461
462 total_enc_len
463 }
464}
465
466pub mod path_extends_path {
472 use super::*;
473
474 #[cfg(feature = "dev")]
475 use arbitrary::Arbitrary;
476
477 pub async fn encode_path_extends_path<const MCL: usize, const MCC: usize, const MPL: usize, C>(
479 path: &Path<MCL, MCC, MPL>,
480 prefix: &Path<MCL, MCC, MPL>,
481 consumer: &mut C,
482 ) -> Result<(), C::Error>
483 where
484 C: BulkConsumer<Item = u8> + ?Sized,
485 {
486 if !path.is_prefixed_by(prefix) {
487 panic!("Tried to encode relative to a non-prefix with PathExtendsPath");
488 }
489
490 let extends_count = prefix.component_count();
491
492 let path_len = path.total_length() - prefix.total_length();
493 let diff = path.component_count() - extends_count;
494
495 encode_from_iterator_of_components(
496 consumer,
497 path_len as u64,
498 diff as u64,
499 path.suffix_components(extends_count),
500 )
501 .await?;
502
503 Ok(())
504 }
505
506 pub fn path_extends_path_encoding_len<const MCL: usize, const MCC: usize, const MPL: usize>(
508 path: &Path<MCL, MCC, MPL>,
509 prefix: &Path<MCL, MCC, MPL>,
510 ) -> usize {
511 let prefix_count = prefix.component_count();
512
513 let path_len = path.total_length() - prefix.total_length();
514 let diff = path.component_count() - prefix_count;
515
516 encoding_len_from_iterator_of_components(
517 path_len as u64,
518 diff,
519 path.suffix_components(prefix_count),
520 )
521 }
522
523 pub async fn decode_path_extends_path<const MCL: usize, const MCC: usize, const MPL: usize, P>(
525 prefix: &Path<MCL, MCC, MPL>,
526 producer: &mut P,
527 ) -> Result<Path<MCL, MCC, MPL>, DecodeError<P::Final, P::Error, Blame>>
528 where
529 P: BulkProducer<Item = u8> + ?Sized,
530 {
531 let suffix = Path::<MCL, MCC, MPL>::decode(producer)
532 .await
533 .map_err(|err| err.map_other(From::from))?;
534
535 let prefix_count = prefix.component_count();
536
537 let total_length = prefix.total_length() + suffix.total_length();
538 let total_count = prefix_count + suffix.component_count();
539
540 let mut path_builder =
541 PathBuilder::new_from_prefix(total_length, total_count, prefix, prefix_count)
542 .map_err(|_err| DecodeError::Other(Blame::TheirFault))?;
543
544 for component in suffix.components() {
545 path_builder.append_component(component);
546 }
547
548 Ok(path_builder.build())
549 }
550
551 pub async fn decode_path_extends_path_canonic<
553 const MCL: usize,
554 const MCC: usize,
555 const MPL: usize,
556 P,
557 >(
558 prefix: &Path<MCL, MCC, MPL>,
559 producer: &mut P,
560 ) -> Result<Path<MCL, MCC, MPL>, DecodeError<P::Final, P::Error, Blame>>
561 where
562 P: BulkProducer<Item = u8> + ?Sized,
563 {
564 let suffix = Path::<MCL, MCC, MPL>::decode_canonic(producer)
565 .await
566 .map_err(|err| err.map_other(From::from))?;
567
568 let prefix_count = prefix.component_count();
569
570 let total_length = prefix.total_length() + suffix.total_length();
571 let total_count = prefix_count + suffix.component_count();
572
573 let mut path_builder =
574 PathBuilder::new_from_prefix(total_length, total_count, prefix, prefix_count)
575 .map_err(|_err| DecodeError::Other(Blame::TheirFault))?;
576
577 for component in suffix.components() {
578 path_builder.append_component(component);
579 }
580
581 Ok(path_builder.build())
582 }
583
584 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default, Debug)]
586 #[cfg_attr(feature = "dev", derive(Arbitrary))]
587 pub struct CodecPathExtendsPath<const MCL: usize, const MCC: usize, const MPL: usize>(
588 pub Path<MCL, MCC, MPL>,
589 );
590
591 impl<const MCL: usize, const MCC: usize, const MPL: usize>
593 RelativeEncodable<Path<MCL, MCC, MPL>> for CodecPathExtendsPath<MCL, MCC, MPL>
594 {
595 async fn relative_encode<C>(
596 &self,
597 rel: &Path<MCL, MCC, MPL>,
598 consumer: &mut C,
599 ) -> Result<(), C::Error>
600 where
601 C: BulkConsumer<Item = u8> + ?Sized,
602 {
603 encode_path_extends_path(&self.0, rel, consumer).await
604 }
605
606 fn can_be_encoded_relative_to(&self, rel: &Path<MCL, MCC, MPL>) -> bool {
608 rel.is_prefix_of(&self.0)
609 }
610 }
611
612 impl<const MCL: usize, const MCC: usize, const MPL: usize>
614 RelativeEncodableKnownLength<Path<MCL, MCC, MPL>> for CodecPathExtendsPath<MCL, MCC, MPL>
615 {
616 fn len_of_relative_encoding(&self, rel: &Path<MCL, MCC, MPL>) -> usize {
617 path_extends_path_encoding_len(&self.0, rel)
618 }
619 }
620
621 impl<const MCL: usize, const MCC: usize, const MPL: usize>
623 RelativeDecodable<Path<MCL, MCC, MPL>> for CodecPathExtendsPath<MCL, MCC, MPL>
624 {
625 type ErrorReason = Blame;
626
627 async fn relative_decode<P>(
628 rel: &Path<MCL, MCC, MPL>,
629 producer: &mut P,
630 ) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>
631 where
632 P: BulkProducer<Item = u8> + ?Sized,
633 Self: Sized,
634 {
635 Ok(Self(decode_path_extends_path(rel, producer).await?))
636 }
637 }
638
639 impl<const MCL: usize, const MCC: usize, const MPL: usize>
641 RelativeDecodableCanonic<Path<MCL, MCC, MPL>> for CodecPathExtendsPath<MCL, MCC, MPL>
642 {
643 type ErrorCanonic = Blame;
644
645 async fn relative_decode_canonic<P>(
646 rel: &Path<MCL, MCC, MPL>,
647 producer: &mut P,
648 ) -> Result<Self, DecodeError<P::Final, P::Error, Self::ErrorReason>>
649 where
650 P: BulkProducer<Item = u8> + ?Sized,
651 Self: Sized,
652 {
653 Ok(Self(decode_path_extends_path_canonic(rel, producer).await?))
654 }
655 }
656}