proto_types/
field_type.rs

1use crate::field_descriptor_proto::Type as ProtoType;
2
3/// An enhanced enum for protobuf types, allowing you to identify well known types such as Any, Timestamp or Duration
4#[derive(Clone, Debug, PartialEq, Eq, Copy)]
5pub enum FieldType {
6  Double,
7  Float,
8  Int64,
9  Uint64,
10  Int32,
11  Fixed64,
12  Fixed32,
13  Bool,
14  String,
15  Bytes,
16  Uint32,
17  Enum,
18  Sfixed32,
19  Sfixed64,
20  Sint32,
21  Sint64,
22  Group,
23  Message,
24  Duration,
25  Timestamp,
26  Any,
27}
28
29impl FieldType {
30  pub fn is_scalar(&self) -> bool {
31    !matches!(
32      self,
33      Self::Message | Self::Duration | Self::Timestamp | Self::Any
34    )
35  }
36
37  /// Returns the short, lowercase name for the field type.
38  pub fn name(&self) -> &'static str {
39    match self {
40      FieldType::Double => "double",
41      FieldType::Float => "float",
42      FieldType::Int64 => "int64",
43      FieldType::Uint64 => "uint64",
44      FieldType::Int32 => "int32",
45      FieldType::Fixed64 => "fixed64",
46      FieldType::Fixed32 => "fixed32",
47      FieldType::Bool => "bool",
48      FieldType::String => "string",
49      FieldType::Bytes => "bytes",
50      FieldType::Uint32 => "uint32",
51      FieldType::Enum => "enum",
52      FieldType::Sfixed32 => "sfixed32",
53      FieldType::Sfixed64 => "sfixed64",
54      FieldType::Sint32 => "sint32",
55      FieldType::Sint64 => "sint64",
56      FieldType::Group => "group",
57      FieldType::Message => "message",
58      FieldType::Duration => "duration",
59      FieldType::Timestamp => "timestamp",
60      FieldType::Any => "any",
61    }
62  }
63
64  /// Returns the full name for the field type, using the
65  /// fully-qualified name for Google's well-known types.
66  pub fn full_name(&self) -> &'static str {
67    match self {
68      // Special cases for well-known types
69      FieldType::Duration => "google.protobuf.Duration",
70      FieldType::Timestamp => "google.protobuf.Timestamp",
71      FieldType::Any => "google.protobuf.Any",
72
73      // For all other types, it falls back to the short name.
74      // The `_` arm catches all variants not matched above.
75      _ => self.name(),
76    }
77  }
78}
79
80impl From<FieldType> for ProtoType {
81  fn from(value: FieldType) -> Self {
82    match value {
83      FieldType::Double => ProtoType::Double,
84      FieldType::Float => ProtoType::Float,
85      FieldType::Int32 => ProtoType::Int32,
86      FieldType::Int64 => ProtoType::Int64,
87      FieldType::Uint32 => ProtoType::Uint32,
88      FieldType::Uint64 => ProtoType::Uint64,
89      FieldType::Sint32 => ProtoType::Sint32,
90      FieldType::Sint64 => ProtoType::Sint64,
91      FieldType::Fixed32 => ProtoType::Fixed32,
92      FieldType::Fixed64 => ProtoType::Fixed64,
93      FieldType::Sfixed32 => ProtoType::Sfixed32,
94      FieldType::Sfixed64 => ProtoType::Sfixed64,
95      FieldType::Bool => ProtoType::Bool,
96      FieldType::String => ProtoType::String,
97      FieldType::Bytes => ProtoType::Bytes,
98      FieldType::Message => ProtoType::Message,
99      FieldType::Enum => ProtoType::Enum,
100      FieldType::Group => ProtoType::Group,
101      FieldType::Duration => ProtoType::Message,
102      FieldType::Timestamp => ProtoType::Message,
103      FieldType::Any => ProtoType::Message,
104    }
105  }
106}
107
108impl From<ProtoType> for FieldType {
109  fn from(value: ProtoType) -> Self {
110    match value {
111      ProtoType::Double => FieldType::Double,
112      ProtoType::Float => FieldType::Float,
113      ProtoType::Int32 => FieldType::Int32,
114      ProtoType::Int64 => FieldType::Int64,
115      ProtoType::Uint32 => FieldType::Uint32,
116      ProtoType::Uint64 => FieldType::Uint64,
117      ProtoType::Sint32 => FieldType::Sint32,
118      ProtoType::Sint64 => FieldType::Sint64,
119      ProtoType::Fixed32 => FieldType::Fixed32,
120      ProtoType::Fixed64 => FieldType::Fixed64,
121      ProtoType::Sfixed32 => FieldType::Sfixed32,
122      ProtoType::Sfixed64 => FieldType::Sfixed64,
123      ProtoType::Bool => FieldType::Bool,
124      ProtoType::String => FieldType::String,
125      ProtoType::Bytes => FieldType::Bytes,
126      ProtoType::Message => FieldType::Message,
127      ProtoType::Enum => FieldType::Enum,
128      ProtoType::Group => FieldType::Group,
129    }
130  }
131}
132
133impl From<FieldType> for i32 {
134  fn from(val: FieldType) -> Self {
135    match val {
136      FieldType::Double => ProtoType::Double.into(),
137      FieldType::Float => ProtoType::Float.into(),
138      FieldType::Int32 => ProtoType::Int32.into(),
139      FieldType::Int64 => ProtoType::Int64.into(),
140      FieldType::Uint32 => ProtoType::Uint32.into(),
141      FieldType::Uint64 => ProtoType::Uint64.into(),
142      FieldType::Sint32 => ProtoType::Sint32.into(),
143      FieldType::Sint64 => ProtoType::Sint64.into(),
144      FieldType::Fixed32 => ProtoType::Fixed32.into(),
145      FieldType::Fixed64 => ProtoType::Fixed64.into(),
146      FieldType::Sfixed32 => ProtoType::Sfixed32.into(),
147      FieldType::Sfixed64 => ProtoType::Sfixed64.into(),
148      FieldType::Bool => ProtoType::Bool.into(),
149      FieldType::String => ProtoType::String.into(),
150      FieldType::Bytes => ProtoType::Bytes.into(),
151      FieldType::Message => ProtoType::Message.into(),
152      FieldType::Enum => ProtoType::Enum.into(),
153      FieldType::Group => ProtoType::Group.into(),
154      FieldType::Duration => ProtoType::Message.into(),
155      FieldType::Timestamp => ProtoType::Message.into(),
156      FieldType::Any => ProtoType::Message.into(),
157    }
158  }
159}
160
161#[cfg(feature = "totokens")]
162mod totokens {
163  use proc_macro2::TokenStream;
164  use quote::{quote, ToTokens};
165
166  use crate::FieldType;
167
168  impl ToTokens for FieldType {
169    fn to_tokens(&self, tokens: &mut TokenStream) {
170      let field_kind_path = quote! { ::protocheck::types::FieldType };
171
172      let variant_tokens = match self {
173        FieldType::Double => quote! { Double },
174        FieldType::Float => quote! { Float },
175        FieldType::Int64 => quote! { Int64 },
176        FieldType::Uint64 => quote! { Uint64 },
177        FieldType::Int32 => quote! { Int32 },
178        FieldType::Fixed64 => quote! { Fixed64 },
179        FieldType::Fixed32 => quote! { Fixed32 },
180        FieldType::Bool => quote! { Bool },
181        FieldType::String => quote! { String },
182        FieldType::Group => quote! { Group },
183        FieldType::Message => quote! { Message },
184        FieldType::Duration => quote! { Duration },
185        FieldType::Timestamp => quote! { Timestamp },
186        FieldType::Any => quote! { Any },
187        FieldType::Bytes => quote! { Bytes },
188        FieldType::Uint32 => quote! { Uint32 },
189        FieldType::Enum => quote! { Enum },
190        FieldType::Sfixed32 => quote! { Sfixed32 },
191        FieldType::Sfixed64 => quote! { Sfixed64 },
192        FieldType::Sint32 => quote! { Sint32 },
193        FieldType::Sint64 => quote! { Sint64 },
194      };
195
196      tokens.extend(quote! { #field_kind_path::#variant_tokens });
197    }
198  }
199}