THRIFT-4529: Rust enum variants are now camel-cased
Client: rs
diff --git a/CHANGES b/CHANGES
index 9533ad0..c24c2b2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,8 @@
Apache Thrift Changelog
Breaking Changes since 0.11.0 [for 0.12.0]:
---------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+ * [THRIFT-4529] - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions
* [THRIFT-4448] - Support for golang 1.6 and earlier has been dropped.
* [THRIFT-4474] - PHP now uses the PSR-4 loader by default instead of class maps.
* [THRIFT-4532] - method signatures changed in the compiler's t_oop_generator.
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index a01c626..fed1a66 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -502,6 +502,9 @@
// the server half of a Thrift service.
string rust_sync_processor_impl_name(t_service *tservice);
+ // Return the variant name for an enum variant
+ string rust_enum_variant_name(const string& name);
+
// Properly uppercase names for use in Rust.
string rust_upper_case(const string& name);
@@ -883,7 +886,7 @@
render_rustdoc((t_doc*) val);
f_gen_
<< indent()
- << uppercase(val->get_name())
+ << rust_enum_variant_name(val->get_name())
<< " = "
<< val->get_value()
<< ","
@@ -944,7 +947,7 @@
f_gen_
<< indent()
<< val->get_value()
- << " => Ok(" << enum_name << "::" << uppercase(val->get_name()) << "),"
+ << " => Ok(" << enum_name << "::" << rust_enum_variant_name(val->get_name()) << "),"
<< endl;
}
f_gen_ << indent() << "_ => {" << endl;
@@ -3279,6 +3282,23 @@
return "T" + rust_camel_case(tservice->get_name()) + "ProcessFunctions";
}
+string t_rs_generator::rust_enum_variant_name(const string &name) {
+ bool all_uppercase = true;
+
+ for (size_t i = 0; i < name.size(); i++) {
+ if (isalnum(name[i]) && islower(name[i])) {
+ all_uppercase = false;
+ break;
+ }
+ }
+
+ if (all_uppercase) {
+ return capitalize(camelcase(lowercase(name)));
+ } else {
+ return capitalize(camelcase(name));
+ }
+}
+
string t_rs_generator::rust_upper_case(const string& name) {
string str(uppercase(underscore(name)));
string_replace(str, "__", "_");
diff --git a/lib/rs/README.md b/lib/rs/README.md
index 8b35eda..7c37a10 100644
--- a/lib/rs/README.md
+++ b/lib/rs/README.md
@@ -37,6 +37,57 @@
Full [Rustdoc](https://docs.rs/thrift/)
+## Compatibility
+
+The Rust library and auto-generated code targets Rust versions 1.28+.
+It does not currently use any Rust 2018 features.
+
+### Breaking Changes
+
+Breaking changes are minimized. When they are made they will be outlined below with transition guidelines.
+
+##### Thrift 0.12.0
+
+* **[THRIFT-4529]** - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions
+
+ Previously, enum variants were uppercased in the auto-generated code.
+ For example, the following thrift enum:
+
+ ```thrift
+ // THRIFT
+ enum Operation {
+ ADD,
+ SUBTRACT,
+ MULTIPLY,
+ DIVIDE,
+ }
+ ```
+
+ used to generate:
+
+ ```rust
+ // OLD AUTO-GENERATED RUST
+ pub enum Operation {
+ ADD,
+ SUBTRACT,
+ MULTIPLY,
+ DIVIDE,
+ }
+ ```
+ It *now* generates:
+ ```rust
+ // NEW AUTO-GENERATED RUST
+ pub enum Operation {
+ Add,
+ Subtract,
+ Multiply,
+ Divide,
+ }
+ ```
+
+ You will have to change all enum variants in your code to use camel-cased names.
+ This should be a search and replace.
+
## Contributing
Bug reports and PRs are always welcome! Please see the
diff --git a/lib/rs/test/src/bin/kitchen_sink_server.rs b/lib/rs/test/src/bin/kitchen_sink_server.rs
index ae70262..e2c4a27 100644
--- a/lib/rs/test/src/bin/kitchen_sink_server.rs
+++ b/lib/rs/test/src/bin/kitchen_sink_server.rs
@@ -17,23 +17,23 @@
#[macro_use]
extern crate clap;
-
extern crate kitchen_sink;
extern crate thrift;
+use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory,
+ TCompactInputProtocolFactory, TCompactOutputProtocolFactory,
+ TInputProtocolFactory, TOutputProtocolFactory};
+use thrift::server::TServer;
+use thrift::transport::{TFramedReadTransportFactory, TFramedWriteTransportFactory,
+ TReadTransportFactory, TWriteTransportFactory};
+
use kitchen_sink::base_one::Noodle;
use kitchen_sink::base_two::{BrothType, Napkin, NapkinServiceSyncHandler, Ramen, RamenServiceSyncHandler};
-use kitchen_sink::midlayer::{Dessert, Meal, MealServiceSyncHandler, MealServiceSyncProcessor};
+use kitchen_sink::midlayer::{Dessert, Meal, MealServiceSyncHandler, MealServiceSyncProcessor, Pie};
use kitchen_sink::recursive;
use kitchen_sink::ultimate::{Drink, FullMeal, FullMealAndDrinks,
FullMealAndDrinksServiceSyncProcessor, FullMealServiceSyncHandler};
use kitchen_sink::ultimate::FullMealAndDrinksServiceSyncHandler;
-use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory,
- TCompactInputProtocolFactory, TCompactOutputProtocolFactory,
- TInputProtocolFactory, TOutputProtocolFactory};
-use thrift::transport::{TFramedReadTransportFactory, TFramedWriteTransportFactory,
- TReadTransportFactory, TWriteTransportFactory};
-use thrift::server::TServer;
fn main() {
match run() {
@@ -207,7 +207,13 @@
impl FullMealAndDrinksServiceSyncHandler for FullHandler {
fn handle_full_meal_and_drinks(&self) -> thrift::Result<FullMealAndDrinks> {
- Ok(FullMealAndDrinks::new(full_meal(), Drink::WHISKEY))
+ println!("full_meal_and_drinks: handling full meal and drinks call");
+ Ok(FullMealAndDrinks::new(full_meal(), Drink::CanadianWhisky))
+ }
+
+ fn handle_best_pie(&self) -> thrift::Result<Pie> {
+ println!("full_meal_and_drinks: handling pie call");
+ Ok(Pie::MississippiMud) // I prefer Pie::Pumpkin, but I have to check that casing works
}
}
@@ -252,7 +258,7 @@
}
fn ramen() -> Ramen {
- Ramen::new("Mr Ramen".to_owned(), 72, BrothType::MISO)
+ Ramen::new("Mr Ramen".to_owned(), 72, BrothType::Miso)
}
fn napkin() -> Napkin {
diff --git a/lib/rs/test/thrifts/Midlayer.thrift b/lib/rs/test/thrifts/Midlayer.thrift
index cf1157c..16ff49b 100644
--- a/lib/rs/test/thrifts/Midlayer.thrift
+++ b/lib/rs/test/thrifts/Midlayer.thrift
@@ -46,6 +46,15 @@
[6, 7, 8]
]
+enum Pie {
+ PUMPKIN,
+ apple, // intentionally poorly cased
+ STRAWBERRY_RHUBARB,
+ Key_Lime, // intentionally poorly cased
+ coconut_Cream, // intentionally poorly cased
+ mississippi_mud, // intentionally poorly cased
+}
+
struct Meal {
1: Base_One.Noodle noodle
2: Base_Two.Ramen ramen
diff --git a/lib/rs/test/thrifts/Ultimate.thrift b/lib/rs/test/thrifts/Ultimate.thrift
index 8154d91..72fa100 100644
--- a/lib/rs/test/thrifts/Ultimate.thrift
+++ b/lib/rs/test/thrifts/Ultimate.thrift
@@ -27,6 +27,21 @@
WATER,
WHISKEY,
WINE,
+ scotch, // intentionally poorly cased
+ LATE_HARVEST_WINE,
+ India_Pale_Ale, // intentionally poorly cased
+ apple_cider, // intentially poorly cased
+ belgian_Ale, // intentionally poorly cased
+ Canadian_whisky, // intentionally poorly cased
+}
+
+const map<i8, Midlayer.Pie> RankedPies = {
+ 1: Midlayer.Pie.PUMPKIN,
+ 2: Midlayer.Pie.STRAWBERRY_RHUBARB,
+ 3: Midlayer.Pie.apple,
+ 4: Midlayer.Pie.mississippi_mud,
+ 5: Midlayer.Pie.coconut_Cream,
+ 6: Midlayer.Pie.Key_Lime,
}
struct FullMeal {
@@ -45,5 +60,7 @@
service FullMealAndDrinksService extends FullMealService {
FullMealAndDrinks fullMealAndDrinks()
+
+ Midlayer.Pie bestPie()
}
diff --git a/test/rs/src/bin/test_client.rs b/test/rs/src/bin/test_client.rs
index 297faf9..29b5b88 100644
--- a/test/rs/src/bin/test_client.rs
+++ b/test/rs/src/bin/test_client.rs
@@ -216,7 +216,7 @@
info!("testEnum");
{
- verify_expected_result(thrift_test_client.test_enum(Numberz::TWO), Numberz::TWO)?;
+ verify_expected_result(thrift_test_client.test_enum(Numberz::Two), Numberz::Two)?;
}
info!("testBinary");
@@ -391,7 +391,7 @@
};
verify_expected_result(
- thrift_test_client.test_multi(1, -123948, -19234123981, m_snd, Numberz::EIGHT, 81),
+ thrift_test_client.test_multi(1, -123948, -19234123981, m_snd, Numberz::Eight, 81),
s_cmp,
)?;
}
@@ -405,8 +405,8 @@
// }
{
let mut arg_map_usermap: BTreeMap<Numberz, i64> = BTreeMap::new();
- arg_map_usermap.insert(Numberz::ONE, 4289);
- arg_map_usermap.insert(Numberz::EIGHT, 19);
+ arg_map_usermap.insert(Numberz::One, 4289);
+ arg_map_usermap.insert(Numberz::Eight, 19);
let mut arg_vec_xtructs: Vec<Xtruct> = Vec::new();
arg_vec_xtructs.push(
@@ -439,15 +439,15 @@
user_map: Some(arg_map_usermap),
xtructs: Some(arg_vec_xtructs),
};
- s_cmp_nested_1.insert(Numberz::TWO, insanity.clone());
- s_cmp_nested_1.insert(Numberz::THREE, insanity.clone());
+ s_cmp_nested_1.insert(Numberz::Two, insanity.clone());
+ s_cmp_nested_1.insert(Numberz::Three, insanity.clone());
let mut s_cmp_nested_2: BTreeMap<Numberz, Insanity> = BTreeMap::new();
let empty_insanity = Insanity {
user_map: Some(BTreeMap::new()),
xtructs: Some(Vec::new()),
};
- s_cmp_nested_2.insert(Numberz::SIX, empty_insanity);
+ s_cmp_nested_2.insert(Numberz::Six, empty_insanity);
let mut s_cmp: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
s_cmp.insert(1 as UserId, s_cmp_nested_1);
diff --git a/test/rs/src/bin/test_server.rs b/test/rs/src/bin/test_server.rs
index 1976bf4..81c1ec7 100644
--- a/test/rs/src/bin/test_server.rs
+++ b/test/rs/src/bin/test_server.rs
@@ -273,15 +273,15 @@
) -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
info!("testInsanity({:?})", argument);
let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
- map_0.insert(Numberz::TWO, argument.clone());
- map_0.insert(Numberz::THREE, argument.clone());
+ map_0.insert(Numberz::Two, argument.clone());
+ map_0.insert(Numberz::Three, argument.clone());
let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
let insanity = Insanity {
user_map: None,
xtructs: None,
};
- map_1.insert(Numberz::SIX, insanity);
+ map_1.insert(Numberz::Six, insanity);
let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
ret.insert(1, map_0);
diff --git a/tutorial/rs/src/bin/tutorial_client.rs b/tutorial/rs/src/bin/tutorial_client.rs
index 24ab4be..e7192b6 100644
--- a/tutorial/rs/src/bin/tutorial_client.rs
+++ b/tutorial/rs/src/bin/tutorial_client.rs
@@ -71,7 +71,7 @@
// let's do...a multiply!
let res = client
- .calculate(logid, Work::new(7, 8, Operation::MULTIPLY, None))?;
+ .calculate(logid, Work::new(7, 8, Operation::Multiply, None))?;
println!("multiplied 7 and 8 and got {}", res);
// let's get the log for it
@@ -81,7 +81,7 @@
// ok - let's be bad :(
// do a divide by 0
// logid doesn't matter; won't be recorded
- let res = client.calculate(77, Work::new(2, 0, Operation::DIVIDE, "we bad".to_owned()));
+ let res = client.calculate(77, Work::new(2, 0, Operation::Divide, "we bad".to_owned()));
// we should have gotten an exception back
match res {
diff --git a/tutorial/rs/src/bin/tutorial_server.rs b/tutorial/rs/src/bin/tutorial_server.rs
index 8db8eed..171c4ce 100644
--- a/tutorial/rs/src/bin/tutorial_server.rs
+++ b/tutorial/rs/src/bin/tutorial_server.rs
@@ -134,10 +134,10 @@
let num2 = w.num2.as_ref().expect("operands checked");
match *op {
- Operation::ADD => Ok(num1 + num2),
- Operation::SUBTRACT => Ok(num1 - num2),
- Operation::MULTIPLY => Ok(num1 * num2),
- Operation::DIVIDE => {
+ Operation::Add => Ok(num1 + num2),
+ Operation::Subtract => Ok(num1 - num2),
+ Operation::Multiply => Ok(num1 * num2),
+ Operation::Divide => {
if *num2 == 0 {
Err(
InvalidOperation {