1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use super::super::util::*;
use super::{
DataTypeBase, Field, FieldOrOneof, FieldOrOneofCase, Message, OneofField,
ONEOF_FIELD_NUMBER_IN_MESSAGE_DESCRIPTOR,
};
use crate::Result;
use ::stable_puroro::protobuf::google::protobuf::{DescriptorProtoView, OneofDescriptorProtoView};
use ::std::fmt::Debug;
use ::std::rc::{Rc, Weak};
#[derive(Debug)]
pub(crate) struct Oneof {
cache: AnonymousCache,
message: Weak<Message>,
oneof_index: usize,
name: String,
fields: Vec<Rc<OneofField>>,
}
impl Oneof {
pub(crate) fn new(
message_proto: &DescriptorProtoView,
oneof_proto: &OneofDescriptorProtoView,
oneof_index: usize,
message: Weak<Message>,
) -> Rc<Oneof> {
Rc::new_cyclic(|weak| {
let fields = message_proto
.field()
.into_iter()
.enumerate()
.filter(|(_, f)| f.oneof_index() as usize == oneof_index)
.map(|(i, f)| OneofField::new(f, Weak::clone(weak), i))
.collect::<Vec<_>>();
Oneof {
cache: Default::default(),
message,
oneof_index,
name: oneof_proto.name().to_string(),
fields,
}
})
}
}
impl DataTypeBase for Oneof {
fn cache(&self) -> &AnonymousCache {
&self.cache
}
fn name(&self) -> Result<&str> {
Ok(&self.name)
}
}
impl FieldOrOneof for Oneof {
fn either(&self) -> FieldOrOneofCase<&Field, &Oneof> {
FieldOrOneofCase::Oneof(self)
}
}
impl Oneof {
pub(crate) fn fields(&self) -> Result<impl Iterator<Item = &Rc<OneofField>>> {
Ok(Box::new(self.fields.iter()))
}
pub(crate) fn message(&self) -> Result<Rc<Message>> {
Ok(self.message.try_upgrade()?)
}
pub(crate) fn location_path(&self) -> Result<impl Iterator<Item = i32>> {
let this_path = [
ONEOF_FIELD_NUMBER_IN_MESSAGE_DESCRIPTOR,
self.oneof_index.try_into()?,
];
Ok(self
.message()?
.location_path()?
.chain(this_path.into_iter()))
}
}