1use std::mem;
2
3use crate::analyse::{Analyze, StatType};
4use crate::v01::StreamMeta;
5use crate::{Decoder, MltError, MltResult};
6
7pub trait Decode<Parsed>: Sized {
8 fn decode(self, decoder: &mut Decoder) -> MltResult<Parsed>;
9}
10
11#[allow(clippy::large_enum_variant)]
15#[derive(Debug, PartialEq, Clone)]
16#[cfg_attr(all(not(test), feature = "arbitrary"), derive(arbitrary::Arbitrary))]
17pub enum EncDec<Raw, Parsed> {
18 Raw(Raw), Parsed(Parsed), ParsingFailed,
21}
22
23impl<Raw: Decode<Parsed>, Parsed> EncDec<Raw, Parsed> {
24 pub fn decode(&mut self, decoder: &mut Decoder) -> MltResult<&mut Parsed> {
26 match self {
27 Self::Parsed(v) => Ok(v),
28 Self::Raw(_) => {
29 let Self::Raw(raw) = mem::replace(self, Self::ParsingFailed) else {
30 unreachable!();
31 };
32 *self = Self::Parsed(raw.decode(decoder)?);
33 let Self::Parsed(v) = self else {
34 unreachable!()
35 };
36 Ok(v)
37 }
38 Self::ParsingFailed => Err(MltError::PriorParseFailure),
39 }
40 }
41
42 pub fn into_parsed(self, decoder: &mut Decoder) -> MltResult<Parsed> {
44 match self {
45 Self::Parsed(v) => Ok(v),
46 Self::Raw(raw) => raw.decode(decoder),
47 Self::ParsingFailed => Err(MltError::PriorParseFailure),
48 }
49 }
50
51 pub fn as_parsed(&self) -> MltResult<&Parsed> {
52 match self {
53 Self::Parsed(v) => Ok(v),
54 Self::Raw(_) => Err(MltError::NotDecoded("enc_dec value")), Self::ParsingFailed => Err(MltError::PriorParseFailure),
56 }
57 }
58}
59
60impl<Raw: Analyze, Parsed: Analyze> Analyze for EncDec<Raw, Parsed> {
61 fn collect_statistic(&self, stat: StatType) -> usize {
62 match self {
63 Self::Raw(encoded) => encoded.collect_statistic(stat),
64 Self::Parsed(decoded) => decoded.collect_statistic(stat),
65 Self::ParsingFailed => 0,
66 }
67 }
68
69 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
70 match self {
71 Self::Raw(encoded) => encoded.for_each_stream(cb),
72 Self::Parsed(decoded) => decoded.for_each_stream(cb),
73 Self::ParsingFailed => {}
74 }
75 }
76}