1use crate::Error;
8use crate::FieldDecode;
9use crate::FieldEncode;
10use crate::MessageDecode;
11use crate::MessageEncode;
12use crate::Result;
13use crate::ResultExt;
14use crate::inplace::InplaceOption;
15use crate::protobuf::FieldReader;
16use crate::protobuf::MessageReader;
17use crate::protobuf::MessageSizer;
18use crate::protobuf::MessageWriter;
19use crate::protofile::DescribeField;
20use crate::protofile::DescribeMessage;
21use crate::protofile::FieldType;
22use crate::protofile::MessageDescription;
23use thiserror::Error;
24
25pub struct OneofEncoder;
30
31#[derive(Debug, Error)]
32#[error("missing enum variant")]
33struct UnassignedEnum;
34
35pub trait OneofEncode<R> {
37 fn write_variant(self, writer: MessageWriter<'_, '_, R>);
39 fn compute_variant_size(&mut self, sizer: MessageSizer<'_>);
41}
42
43pub trait DescribeOneof {
45 const DESCRIPTION: MessageDescription<'static>;
47}
48
49impl<T: DescribeOneof> DescribeMessage<T> for OneofEncoder {
50 const DESCRIPTION: MessageDescription<'static> = T::DESCRIPTION;
51}
52
53impl<T: DescribeOneof> DescribeField<T> for OneofEncoder {
54 const FIELD_TYPE: FieldType<'static> = FieldType::message(|| T::DESCRIPTION);
55}
56
57impl<T: OneofEncode<R>, R> MessageEncode<T, R> for OneofEncoder {
58 fn write_message(item: T, writer: MessageWriter<'_, '_, R>) {
59 item.write_variant(writer)
60 }
61
62 fn compute_message_size(item: &mut T, sizer: MessageSizer<'_>) {
63 item.compute_variant_size(sizer)
64 }
65}
66
67impl<T: OneofEncode<R>, R> FieldEncode<T, R> for OneofEncoder {
68 fn write_field(item: T, writer: crate::protobuf::FieldWriter<'_, '_, R>) {
69 writer.message(|writer| item.write_variant(writer))
70 }
71
72 fn compute_field_size(item: &mut T, sizer: crate::protobuf::FieldSizer<'_>) {
73 sizer.message(|sizer| item.compute_variant_size(sizer))
74 }
75}
76
77pub trait OneofDecode<'de, R>: Sized {
79 fn read_variant(
81 this: &mut InplaceOption<'_, Self>,
82 number: u32,
83 reader: FieldReader<'de, '_, R>,
84 ) -> Result<()>;
85}
86
87impl<'de, T: OneofDecode<'de, R>, R> MessageDecode<'de, T, R> for OneofEncoder {
88 fn read_message(
89 item: &mut InplaceOption<'_, T>,
90 reader: MessageReader<'de, '_, R>,
91 ) -> Result<()> {
92 for field in reader {
93 let (n, field) = field.typed::<T>()?;
94 T::read_variant(item, n, field)?;
95 }
96 if item.is_none() {
97 return Err(Error::new(UnassignedEnum).typed::<T>());
98 }
99 Ok(())
100 }
101}
102
103impl<'de, T: OneofDecode<'de, R>, R> FieldDecode<'de, T, R> for OneofEncoder {
107 fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'de, '_, R>) -> Result<()> {
108 Self::read_message(item, reader.message()?)
109 }
110
111 fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<()> {
112 Err(Error::new(UnassignedEnum).typed::<T>())
113 }
114}