Skip to content

Commit c558f0f

Browse files
committed
First test for dynamic messages
1 parent 390a069 commit c558f0f

File tree

7 files changed

+132
-6
lines changed

7 files changed

+132
-6
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use protobuf::reflect::FileDescriptor;
2+
use protobuf::reflect::ReflectValueRef;
3+
4+
use super::test_dynamic_pb;
5+
6+
fn do_test(file_descriptor: &FileDescriptor) {
7+
let m = file_descriptor
8+
.get_message_by_package_relative_name("ForDynamicTest")
9+
.unwrap();
10+
let f = m.get_field_by_name("ff").unwrap();
11+
12+
let mut m = m.new_instance();
13+
let m = &mut *m;
14+
assert_eq!(None, f.get_singular(m));
15+
16+
f.set_singular_field(m, 10u32.into());
17+
assert_eq!(Some(ReflectValueRef::from(10u32)), f.get_singular(m));
18+
}
19+
20+
#[test]
21+
fn test_generated() {
22+
do_test(&test_dynamic_pb::file_descriptor());
23+
}
24+
25+
#[test]
26+
fn test_dynamic() {
27+
do_test(&FileDescriptor::new_dynamic(
28+
test_dynamic_pb::file_descriptor().get_proto().clone(),
29+
Vec::new(),
30+
));
31+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
syntax = "proto2";
2+
3+
message ForDynamicTest {
4+
optional uint32 ff = 1;
5+
}

protobuf/src/reflect/dynamic/mod.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ use crate::reflect::FieldDescriptor;
1010
use crate::reflect::MessageDescriptor;
1111
use crate::reflect::ReflectFieldRef;
1212
use crate::reflect::ReflectMapMut;
13+
use crate::reflect::ReflectMapRef;
1314
use crate::reflect::ReflectRepeatedMut;
15+
use crate::reflect::ReflectRepeatedRef;
16+
use crate::reflect::ReflectValueBox;
1417
use crate::reflect::RuntimeFieldType;
1518
use crate::Clear;
1619
use crate::CodedInputStream;
@@ -33,9 +36,9 @@ enum DynamicFieldValue {
3336
impl DynamicFieldValue {
3437
fn as_ref(&self) -> ReflectFieldRef {
3538
match self {
36-
DynamicFieldValue::Singular(_v) => unimplemented!(),
37-
DynamicFieldValue::Repeated(_r) => unimplemented!(),
38-
DynamicFieldValue::Map(_r) => unimplemented!(),
39+
DynamicFieldValue::Singular(v) => ReflectFieldRef::Optional(v.get()),
40+
DynamicFieldValue::Repeated(r) => ReflectFieldRef::Repeated(ReflectRepeatedRef::new(r)),
41+
DynamicFieldValue::Map(m) => ReflectFieldRef::Map(ReflectMapRef::new(m)),
3942
}
4043
}
4144

@@ -152,6 +155,16 @@ impl DynamicMessage {
152155
}
153156
}
154157

158+
pub(crate) fn set_field(&mut self, field: &FieldDescriptor, value: ReflectValueBox) {
159+
assert_eq!(field.message_descriptor, self.descriptor);
160+
self.init_fields();
161+
// TODO: reset oneof group fields
162+
match &mut self.fields[field.index] {
163+
DynamicFieldValue::Singular(s) => s.set(value),
164+
_ => panic!("Not a singular field: {}", field),
165+
}
166+
}
167+
155168
pub fn downcast_ref(message: &dyn MessageDyn) -> &DynamicMessage {
156169
MessageDyn::downcast_ref(message).unwrap()
157170
}

protobuf/src/reflect/dynamic/optional.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::reflect::value::value_ref::ReflectValueMut;
2-
use crate::reflect::{ReflectValueBox, RuntimeTypeBox};
2+
use crate::reflect::ReflectValueBox;
3+
use crate::reflect::ReflectValueRef;
4+
use crate::reflect::RuntimeTypeBox;
35

46
#[derive(Debug, Clone)]
57
pub(crate) struct DynamicOptional {
@@ -22,4 +24,13 @@ impl DynamicOptional {
2224
pub fn clear(&mut self) {
2325
self.value = None;
2426
}
27+
28+
pub fn get(&self) -> Option<ReflectValueRef> {
29+
self.value.as_ref().map(ReflectValueBox::as_value_ref)
30+
}
31+
32+
pub fn set(&mut self, value: ReflectValueBox) {
33+
assert_eq!(value.get_type(), self.elem);
34+
self.value = Some(value);
35+
}
2536
}

protobuf/src/reflect/field/dynamic.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::reflect::FieldDescriptor;
44
use crate::reflect::ReflectFieldRef;
55
use crate::reflect::ReflectMapMut;
66
use crate::reflect::ReflectRepeatedMut;
7+
use crate::reflect::ReflectValueBox;
78

89
pub(crate) struct DynamicFieldDescriptorRef<'a> {
910
pub(crate) field: &'a FieldDescriptor,
@@ -24,4 +25,8 @@ impl<'a> DynamicFieldDescriptorRef<'a> {
2425
pub(crate) fn mut_map<'b>(&self, message: &'b mut dyn MessageDyn) -> ReflectMapMut<'b> {
2526
DynamicMessage::downcast_mut(message).mut_map(&self.field)
2627
}
28+
29+
pub(crate) fn set_field(&self, message: &mut dyn MessageDyn, value: ReflectValueBox) {
30+
DynamicMessage::downcast_mut(message).set_field(&self.field, value)
31+
}
2732
}

protobuf/src/reflect/field/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl FieldDescriptor {
321321
pub fn set_singular_field(&self, m: &mut dyn MessageDyn, value: ReflectValueBox) {
322322
match self.singular() {
323323
SingularFieldAccessorRef::Generated(g) => g.accessor.set_field(m, value),
324-
SingularFieldAccessorRef::Dynamic(..) => unimplemented!(), // TODO
324+
SingularFieldAccessorRef::Dynamic(d) => d.set_field(m, value),
325325
}
326326
}
327327

@@ -342,7 +342,14 @@ impl FieldDescriptor {
342342
}
343343
}
344344

345-
fn get_singular<'a>(&self, m: &'a dyn MessageDyn) -> Option<ReflectValueRef<'a>> {
345+
/// Get singular field value.
346+
///
347+
/// Return `None` if field is unset.
348+
///
349+
/// # Panics
350+
///
351+
/// If this field belongs to a different message type or fields is not singular.
352+
pub fn get_singular<'a>(&self, m: &'a dyn MessageDyn) -> Option<ReflectValueRef<'a>> {
346353
match self.get_reflect(m) {
347354
ReflectFieldRef::Optional(o) => o,
348355
_ => panic!("not a singular field"),

protobuf/src/reflect/value/value_ref.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,57 @@ impl<'a> From<EnumValueDescriptor> for ReflectValueRef<'a> {
267267
ReflectValueRef::Enum(v.enum_descriptor, number)
268268
}
269269
}
270+
271+
impl From<u32> for ReflectValueRef<'_> {
272+
fn from(v: u32) -> Self {
273+
ReflectValueRef::U32(v)
274+
}
275+
}
276+
277+
impl From<i32> for ReflectValueRef<'_> {
278+
fn from(v: i32) -> Self {
279+
ReflectValueRef::I32(v)
280+
}
281+
}
282+
283+
impl From<u64> for ReflectValueRef<'_> {
284+
fn from(v: u64) -> Self {
285+
ReflectValueRef::U64(v)
286+
}
287+
}
288+
289+
impl From<i64> for ReflectValueRef<'_> {
290+
fn from(v: i64) -> Self {
291+
ReflectValueRef::I64(v)
292+
}
293+
}
294+
295+
impl From<f32> for ReflectValueRef<'_> {
296+
fn from(v: f32) -> Self {
297+
ReflectValueRef::F32(v)
298+
}
299+
}
300+
301+
impl From<f64> for ReflectValueRef<'_> {
302+
fn from(v: f64) -> Self {
303+
ReflectValueRef::F64(v)
304+
}
305+
}
306+
307+
impl From<bool> for ReflectValueRef<'_> {
308+
fn from(v: bool) -> Self {
309+
ReflectValueRef::Bool(v)
310+
}
311+
}
312+
313+
impl<'a> From<&'a str> for ReflectValueRef<'a> {
314+
fn from(v: &'a str) -> Self {
315+
ReflectValueRef::String(v)
316+
}
317+
}
318+
319+
impl<'a> From<&'a [u8]> for ReflectValueRef<'a> {
320+
fn from(v: &'a [u8]) -> Self {
321+
ReflectValueRef::Bytes(v)
322+
}
323+
}

0 commit comments

Comments
 (0)