1 //! Utilities to support "extension" fields.
2 //!
3 //! This is a stopgap implementation, it only allows to fetch basic singular values,
4 //! and that's it. Anything similar to extension registry is not implemented yet.
5 //!
6 //! Extensions are [described in the official protobuf documentation][exts].
7 //!
8 //! [exts]: https://developers.google.com/protocol-buffers/docs/proto#extensions
9 
10 use std::marker::PhantomData;
11 
12 use crate::descriptor::field_descriptor_proto::Type;
13 use crate::reflect::runtime_types::RuntimeTypeTrait;
14 use crate::reflect::ProtobufValue;
15 use crate::Message;
16 
17 /// Optional ext field
18 ///
19 /// This is initialized from generated code, do not instantiate directly.
20 pub struct ExtFieldOptional<M, T> {
21     /// Extension field number.
22     field_number: u32,
23     /// Extension field type.
24     field_type: Type,
25     /// Marker
26     phantom: PhantomData<(M, T)>,
27 }
28 
29 /// Repeated ext field
30 ///
31 /// This is initialized from generated code, do not instantiate directly.
32 pub struct ExtFieldRepeated<M, V> {
33     /// Extension field number
34     #[allow(dead_code)]
35     field_number: u32,
36     /// Field type.
37     #[allow(dead_code)]
38     field_type: Type,
39     /// Extension field number
40     phantom: PhantomData<(M, V)>,
41 }
42 
43 impl<M, V> ExtFieldOptional<M, V> {
44     /// Constructor. Called from generated code.
new(field_number: u32, field_type: Type) -> Self45     pub const fn new(field_number: u32, field_type: Type) -> Self {
46         ExtFieldOptional {
47             field_number,
48             field_type,
49             phantom: PhantomData,
50         }
51     }
52 }
53 
54 impl<M: Message, V: ProtobufValue> ExtFieldOptional<M, V> {
55     /// Get a copy of value from a message.
56     ///
57     /// Extension data is stored in [`UnknownFields`](crate::UnknownFields).
get(&self, m: &M) -> Option<V>58     pub fn get(&self, m: &M) -> Option<V> {
59         m.unknown_fields()
60             .get(self.field_number)
61             .and_then(|u| V::RuntimeType::get_from_unknown(u, self.field_type))
62     }
63 }
64 
65 impl<M, V> ExtFieldRepeated<M, V> {
66     /// Constructor. Called from generated code.
new(field_number: u32, field_type: Type) -> Self67     pub const fn new(field_number: u32, field_type: Type) -> Self {
68         ExtFieldRepeated {
69             field_number,
70             field_type,
71             phantom: PhantomData,
72         }
73     }
74 }
75 
76 impl<M: Message, V: ProtobufValue> ExtFieldRepeated<M, V> {
77     /// Get a copy of value from a message (**not implemented**).
get(&self, _m: &M) -> Vec<V>78     pub fn get(&self, _m: &M) -> Vec<V> {
79         unimplemented!("extension fields implementation in rust-protobuf is stopgap")
80     }
81 }
82