aboutsummaryrefslogtreecommitdiff
path: root/src/enums.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/enums.rs')
-rw-r--r--src/enums.rs377
1 files changed, 0 insertions, 377 deletions
diff --git a/src/enums.rs b/src/enums.rs
deleted file mode 100644
index ec3444e..0000000
--- a/src/enums.rs
+++ /dev/null
@@ -1,377 +0,0 @@
-use std::collections::HashSet;
-
-use file_descriptor::file_descriptor_proto_expr;
-use inside::protobuf_crate_path;
-use protobuf::descriptor::*;
-use protobuf_name::ProtobufAbsolutePath;
-use rust_types_values::type_name_to_rust_relative;
-use scope::EnumWithScope;
-use scope::RootScope;
-use scope::WithScope;
-use serde;
-use CodeWriter;
-
-use crate::customize::customize_from_rustproto_for_enum;
-use crate::Customize;
-
-#[derive(Clone)]
-pub struct EnumValueGen {
- proto: EnumValueDescriptorProto,
- enum_rust_name: String,
- variant_rust_name: String,
-}
-
-impl EnumValueGen {
- fn parse(
- proto: &EnumValueDescriptorProto,
- enum_rust_name: &str,
- variant_rust_name: &str,
- ) -> EnumValueGen {
- EnumValueGen {
- proto: proto.clone(),
- enum_rust_name: enum_rust_name.to_string(),
- variant_rust_name: variant_rust_name.to_string(),
- }
- }
-
- // enum value
- fn number(&self) -> i32 {
- self.proto.get_number()
- }
-
- // name of enum variant in generated rust code
- fn rust_name_inner(&self) -> String {
- self.variant_rust_name.clone()
- }
-
- pub fn rust_name_outer(&self) -> String {
- let mut r = String::new();
- r.push_str(&self.enum_rust_name);
- r.push_str("::");
- r.push_str(&self.rust_name_inner());
- r
- }
-}
-
-pub(crate) struct EnumGen<'a> {
- enum_with_scope: &'a EnumWithScope<'a>,
- type_name: String,
- lite_runtime: bool,
- customize: Customize,
-}
-
-impl<'a> EnumGen<'a> {
- pub fn new(
- enum_with_scope: &'a EnumWithScope<'a>,
- current_file: &FileDescriptorProto,
- customize: &Customize,
- root_scope: &RootScope,
- ) -> EnumGen<'a> {
- let rust_name = if enum_with_scope.get_scope().get_file_descriptor().get_name()
- == current_file.get_name()
- {
- // field type is a message or enum declared in the same file
- enum_with_scope.rust_name().to_string()
- } else {
- type_name_to_rust_relative(
- &ProtobufAbsolutePath::from(enum_with_scope.name_absolute()),
- current_file,
- false,
- root_scope,
- customize,
- )
- .to_string()
- };
- let lite_runtime = customize.lite_runtime.unwrap_or_else(|| {
- enum_with_scope
- .get_scope()
- .get_file_descriptor()
- .get_options()
- .get_optimize_for()
- == FileOptions_OptimizeMode::LITE_RUNTIME
- });
-
- let mut customize = customize.clone();
- customize.update_with(&customize_from_rustproto_for_enum(
- enum_with_scope.en.options.as_ref().unwrap_or_default(),
- ));
-
- EnumGen {
- enum_with_scope,
- type_name: rust_name,
- lite_runtime,
- customize,
- }
- }
-
- fn allow_alias(&self) -> bool {
- self.enum_with_scope.en.get_options().get_allow_alias()
- }
-
- fn values_all(&self) -> Vec<EnumValueGen> {
- let mut r = Vec::new();
- for p in self.enum_with_scope.values() {
- r.push(EnumValueGen::parse(
- &p.proto,
- &self.type_name,
- p.rust_name().get(),
- ));
- }
- r
- }
-
- pub fn values_unique(&self) -> Vec<EnumValueGen> {
- let mut used = HashSet::new();
- let mut r = Vec::new();
- for p in self.enum_with_scope.values() {
- // skipping non-unique enums
- // TODO: should support it
- if !used.insert(p.proto.get_number()) {
- continue;
- }
- r.push(EnumValueGen::parse(
- p.proto,
- &self.type_name,
- p.rust_name().get(),
- ));
- }
- r
- }
-
- // find enum value by name
- pub fn value_by_name(&'a self, name: &str) -> EnumValueGen {
- let v = self.enum_with_scope.value_by_name(name);
- EnumValueGen::parse(v.proto, &self.type_name, v.rust_name().get())
- }
-
- pub fn write(&self, w: &mut CodeWriter) {
- self.write_struct(w);
- if self.allow_alias() {
- w.write_line("");
- self.write_impl_eq(w);
- w.write_line("");
- self.write_impl_hash(w);
- }
- w.write_line("");
- self.write_impl_enum(w);
- w.write_line("");
- self.write_impl_copy(w);
- w.write_line("");
- self.write_impl_default(w);
- w.write_line("");
- self.write_impl_value(w);
- }
-
- fn write_struct(&self, w: &mut CodeWriter) {
- let mut derive = Vec::new();
- derive.push("Clone");
- if !self.allow_alias() {
- derive.push("PartialEq");
- }
- derive.push("Eq");
- derive.push("Debug");
- if !self.allow_alias() {
- derive.push("Hash");
- } else {
- w.comment("Note: you cannot use pattern matching for enums with allow_alias option");
- }
- w.derive(&derive);
- serde::write_serde_attr(
- w,
- &self.customize,
- "derive(::serde::Serialize, ::serde::Deserialize)",
- );
- if let Some(ref ren) = self.customize.serde_rename_all {
- let attr = format!("serde(rename_all = \"{}\")", ren);
- serde::write_serde_attr(w, &self.customize, &attr);
- }
- let ref type_name = self.type_name;
- w.expr_block(&format!("pub enum {}", type_name), |w| {
- for value in self.values_all() {
- if self.allow_alias() {
- w.write_line(&format!(
- "{}, // {}",
- value.rust_name_inner(),
- value.number()
- ));
- } else {
- w.write_line(&format!(
- "{} = {},",
- value.rust_name_inner(),
- value.number()
- ));
- }
- }
- });
- }
-
- fn write_fn_value(&self, w: &mut CodeWriter) {
- w.def_fn("value(&self) -> i32", |w| {
- if self.allow_alias() {
- w.match_expr("*self", |w| {
- for value in self.values_all() {
- w.case_expr(value.rust_name_outer(), format!("{}", value.number()));
- }
- });
- } else {
- w.write_line("*self as i32")
- }
- });
- }
-
- fn write_impl_enum(&self, w: &mut CodeWriter) {
- let ref type_name = self.type_name;
- w.impl_for_block(
- &format!("{}::ProtobufEnum", protobuf_crate_path(&self.customize)),
- &format!("{}", type_name),
- |w| {
- self.write_fn_value(w);
-
- w.write_line("");
- let ref type_name = self.type_name;
- w.def_fn(
- &format!(
- "from_i32(value: i32) -> ::std::option::Option<{}>",
- type_name
- ),
- |w| {
- w.match_expr("value", |w| {
- let values = self.values_unique();
- for value in values {
- w.write_line(&format!(
- "{} => ::std::option::Option::Some({}),",
- value.number(),
- value.rust_name_outer()
- ));
- }
- w.write_line(&format!("_ => ::std::option::Option::None"));
- });
- },
- );
-
- w.write_line("");
- w.def_fn(&format!("values() -> &'static [Self]"), |w| {
- w.write_line(&format!("static values: &'static [{}] = &[", type_name));
- w.indented(|w| {
- for value in self.values_all() {
- w.write_line(&format!("{},", value.rust_name_outer()));
- }
- });
- w.write_line("];");
- w.write_line("values");
- });
-
- if !self.lite_runtime {
- w.write_line("");
- w.def_fn(
- &format!(
- "enum_descriptor_static() -> &'static {}::reflect::EnumDescriptor",
- protobuf_crate_path(&self.customize)
- ),
- |w| {
- w.lazy_static_decl_get(
- "descriptor",
- &format!(
- "{}::reflect::EnumDescriptor",
- protobuf_crate_path(&self.customize)
- ),
- &self.customize,
- |w| {
- let ref type_name = self.type_name;
- w.write_line(&format!(
- "{}::reflect::EnumDescriptor::new_pb_name::<{}>(\"{}\", {})",
- protobuf_crate_path(&self.customize),
- type_name,
- self.enum_with_scope.name_to_package(),
- file_descriptor_proto_expr(&self.enum_with_scope.scope)
- ));
- },
- );
- },
- );
- }
- },
- );
- }
-
- fn write_impl_value(&self, w: &mut CodeWriter) {
- w.impl_for_block(
- &format!(
- "{}::reflect::ProtobufValue",
- protobuf_crate_path(&self.customize)
- ),
- &format!("{}", self.type_name),
- |w| {
- w.def_fn(
- &format!(
- "as_ref(&self) -> {}::reflect::ReflectValueRef",
- protobuf_crate_path(&self.customize)
- ),
- |w| {
- w.write_line(&format!(
- "{}::reflect::ReflectValueRef::Enum({}::ProtobufEnum::descriptor(self))",
- protobuf_crate_path(&self.customize),
- protobuf_crate_path(&self.customize)
- ))
- },
- )
- },
- )
- }
-
- fn write_impl_copy(&self, w: &mut CodeWriter) {
- w.impl_for_block("::std::marker::Copy", &self.type_name, |_w| {});
- }
-
- fn write_impl_eq(&self, w: &mut CodeWriter) {
- assert!(self.allow_alias());
- w.impl_for_block(
- "::std::cmp::PartialEq",
- &format!("{}", self.type_name),
- |w| {
- w.def_fn("eq(&self, other: &Self) -> bool", |w| {
- w.write_line(&format!(
- "{}::ProtobufEnum::value(self) == {}::ProtobufEnum::value(other)",
- protobuf_crate_path(&self.customize),
- protobuf_crate_path(&self.customize)
- ));
- });
- },
- );
- }
-
- fn write_impl_hash(&self, w: &mut CodeWriter) {
- assert!(self.allow_alias());
- w.impl_for_block("::std::hash::Hash", &format!("{}", self.type_name), |w| {
- w.def_fn("hash<H : ::std::hash::Hasher>(&self, state: &mut H)", |w| {
- w.write_line(&format!(
- "state.write_i32({}::ProtobufEnum::value(self))",
- protobuf_crate_path(&self.customize)
- ));
- });
- });
- }
-
- fn write_impl_default(&self, w: &mut CodeWriter) {
- let first_value = &self.enum_with_scope.values()[0];
- if first_value.proto.get_number() != 0 {
- // This warning is emitted only for proto2
- // (because in proto3 first enum variant number is always 0).
- // `Default` implemented unconditionally to simplify certain
- // generic operations, e. g. reading a map.
- // Also, note that even in proto2 some operations fallback to
- // first enum value, e. g. `get_xxx` for unset field,
- // so this implementation is not completely unreasonable.
- w.comment("Note, `Default` is implemented although default value is not 0");
- }
- w.impl_for_block("::std::default::Default", &self.type_name, |w| {
- w.def_fn("default() -> Self", |w| {
- w.write_line(&format!(
- "{}::{}",
- &self.type_name,
- &first_value.rust_name()
- ))
- });
- });
- }
-}