summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen George <allengeorge@apache.org>2021-03-11 08:25:26 -0500
committerGitHub <noreply@github.com>2021-03-11 08:25:26 -0500
commitde6f61aed04e4de8e51ae44fa634451e77f17a52 (patch)
tree7c3217e773cfc886ddf1f74f5773a3304d8963a6
parentf926d84a4824b136611f95b78e4064fda5966b9e (diff)
downloadthrift-de6f61aed04e4de8e51ae44fa634451e77f17a52.tar.gz
THRIFT-4098 Namespace support for generated Rust code (#2348)
Client: rs
-rw-r--r--.gitignore11
-rw-r--r--compiler/cpp/src/thrift/generate/t_rs_generator.cc26
-rwxr-xr-xconfigure.ac6
-rw-r--r--lib/rs/Makefile.am1
-rw-r--r--lib/rs/test_recursive/Cargo.toml9
-rw-r--r--lib/rs/test_recursive/Makefile.am33
-rw-r--r--lib/rs/test_recursive/src/Makefile.am33
-rw-r--r--lib/rs/test_recursive/src/Vehicles.thrift35
-rw-r--r--lib/rs/test_recursive/src/lib.rs276
-rw-r--r--lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift37
-rw-r--r--lib/rs/test_recursive/src/maintenance/Makefile.am33
-rw-r--r--lib/rs/test_recursive/src/maintenance/mod.rs18
-rw-r--r--lib/rs/test_recursive/src/transit/Buses.thrift56
-rw-r--r--lib/rs/test_recursive/src/transit/Makefile.am40
-rw-r--r--lib/rs/test_recursive/src/transit/Trains.thrift33
-rw-r--r--lib/rs/test_recursive/src/transit/Transporters.thrift40
-rw-r--r--lib/rs/test_recursive/src/transit/light/LightRail.thrift48
-rw-r--r--lib/rs/test_recursive/src/transit/light/Makefile.am36
-rw-r--r--lib/rs/test_recursive/src/transit/light/Streetcars.thrift72
-rw-r--r--lib/rs/test_recursive/src/transit/light/mod.rs19
-rw-r--r--lib/rs/test_recursive/src/transit/mod.rs22
-rw-r--r--lib/rs/test_recursive/src/transit/services/CityServices.thrift29
-rw-r--r--lib/rs/test_recursive/src/transit/services/Makefile.am33
-rw-r--r--lib/rs/test_recursive/src/transit/services/mod.rs18
24 files changed, 956 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index 80111b3d0..603838fca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -299,6 +299,17 @@ project.lock.json
/lib/rs/test/src/recursive.rs
/lib/rs/test/src/ultimate.rs
/lib/rs/test/src/identifiers.rs
+/lib/rs/test_recursive/Cargo.lock
+/lib/rs/test_recursive/src/vehicles.rs
+/lib/rs/test_recursive/src/maintenance/maintenance_facility.rs
+/lib/rs/test_recursive/src/transit/buses.rs
+/lib/rs/test_recursive/src/transit/trains.rs
+/lib/rs/test_recursive/src/transit/transporters.rs
+/lib/rs/test_recursive/src/transit/light/light_rail.rs
+/lib/rs/test_recursive/src/transit/light/streetcars.rs
+/lib/rs/test_recursive/src/transit/services/city_services.rs
+/lib/rs/test_recursive/target/
+/lib/rs/test_recursive/bin/
/lib/rs/*.iml
/lib/rs/**/*.iml
/lib/swift/.build
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index e11360426..40905c557 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -26,9 +26,10 @@
using std::map;
using std::ofstream;
using std::ostringstream;
+using std::pair;
+using std::set;
using std::string;
using std::vector;
-using std::set;
static const string endl("\n"); // avoid ostream << std::endl flushes
static const string SERVICE_RESULT_VARIABLE("result_value");
@@ -105,7 +106,7 @@ private:
void render_attributes_and_includes();
// Create the closure of Rust modules referenced by this service.
- void compute_service_referenced_modules(t_service *tservice, set<string> &referenced_modules);
+ void compute_service_referenced_modules(t_service *tservice, set<pair<string, string>> &referenced_modules);
// Write the rust representation of an enum.
void render_enum_definition(t_enum* tenum, const string& enum_name);
@@ -583,13 +584,13 @@ void t_rs_generator::render_attributes_and_includes() {
// NOTE: this is more involved than you would expect because of service extension
// Basically, I have to find the closure of all the services and include their modules at the top-level
- set<string> referenced_modules;
+ set<pair<string, string>> referenced_modules; // set<module, namespace>
// first, start by adding explicit thrift includes
const vector<t_program*> includes = get_program()->get_includes();
vector<t_program*>::const_iterator includes_iter;
for(includes_iter = includes.begin(); includes_iter != includes.end(); ++includes_iter) {
- referenced_modules.insert((*includes_iter)->get_name());
+ referenced_modules.insert(std::make_pair((*includes_iter)->get_name(), (*includes_iter)->get_namespace("rs")));
}
// next, recursively iterate through all the services and add the names of any programs they reference
@@ -601,9 +602,18 @@ void t_rs_generator::render_attributes_and_includes() {
// finally, write all the "pub use..." declarations
if (!referenced_modules.empty()) {
- set<string>::iterator module_iter;
+ set<pair<string, string>>::iterator module_iter;
for (module_iter = referenced_modules.begin(); module_iter != referenced_modules.end(); ++module_iter) {
- f_gen_ << "use crate::" << rust_snake_case(*module_iter) << ";" << endl;
+ string module_name((*module_iter).first);
+
+ string module_namespace((*module_iter).second);
+ string_replace(module_namespace, ".", "::");
+
+ if (module_namespace.empty()) {
+ f_gen_ << "use crate::" << rust_snake_case(module_name) << ";" << endl;
+ } else {
+ f_gen_ << "use crate::" << module_namespace << "::" << rust_snake_case(module_name) << ";" << endl;
+ }
}
f_gen_ << endl;
}
@@ -611,12 +621,12 @@ void t_rs_generator::render_attributes_and_includes() {
void t_rs_generator::compute_service_referenced_modules(
t_service *tservice,
- set<string> &referenced_modules
+ set<pair<string, string>> &referenced_modules
) {
t_service* extends = tservice->get_extends();
if (extends) {
if (extends->get_program() != get_program()) {
- referenced_modules.insert(extends->get_program()->get_name());
+ referenced_modules.insert(std::make_pair(extends->get_program()->get_name(), extends->get_program()->get_namespace("rs")));
}
compute_service_referenced_modules(extends, referenced_modules);
}
diff --git a/configure.ac b/configure.ac
index a70a812f8..98327f43b 100755
--- a/configure.ac
+++ b/configure.ac
@@ -797,6 +797,12 @@ AC_CONFIG_FILES([
lib/rb/Makefile
lib/rs/Makefile
lib/rs/test/Makefile
+ lib/rs/test_recursive/Makefile
+ lib/rs/test_recursive/src/Makefile
+ lib/rs/test_recursive/src/maintenance/Makefile
+ lib/rs/test_recursive/src/transit/Makefile
+ lib/rs/test_recursive/src/transit/light/Makefile
+ lib/rs/test_recursive/src/transit/services/Makefile
lib/lua/Makefile
lib/swift/Makefile
lib/ts/Makefile
diff --git a/lib/rs/Makefile.am b/lib/rs/Makefile.am
index 4abdff844..7a9b30a4f 100644
--- a/lib/rs/Makefile.am
+++ b/lib/rs/Makefile.am
@@ -21,6 +21,7 @@ SUBDIRS = .
if WITH_TESTS
SUBDIRS += test
+SUBDIRS += test_recursive
endif
install:
diff --git a/lib/rs/test_recursive/Cargo.toml b/lib/rs/test_recursive/Cargo.toml
new file mode 100644
index 000000000..6b2aa8591
--- /dev/null
+++ b/lib/rs/test_recursive/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "thrift_4098_custom_rust_namespace_support"
+description = "Test namespace support in generated thrift files using recursive Make generation"
+version = "0.1.0"
+authors = ["Allen George <allengeorge@apache.org>"]
+edition = "2018"
+
+[dependencies]
+thrift = { path = "../" }
diff --git a/lib/rs/test_recursive/Makefile.am b/lib/rs/test_recursive/Makefile.am
new file mode 100644
index 000000000..e676ccdca
--- /dev/null
+++ b/lib/rs/test_recursive/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+SUBDIRS = src
+
+check:
+ $(CARGO) fmt --all -- --check
+ $(CARGO) clippy --all -- -D warnings
+ $(CARGO) build
+ $(CARGO) test
+
+clean-local:
+ $(CARGO) clean
+ -$(RM) Cargo.lock
+
+EXTRA_DIST = \
+ Cargo.toml
diff --git a/lib/rs/test_recursive/src/Makefile.am b/lib/rs/test_recursive/src/Makefile.am
new file mode 100644
index 000000000..c21a94cd2
--- /dev/null
+++ b/lib/rs/test_recursive/src/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+SUBDIRS = . transit maintenance
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+stubs: Vehicles.thrift $(THRIFT)
+ $(THRIFT) -I . -out . --gen rs Vehicles.thrift
+
+check: stubs
+
+clean-local:
+ -$(RM) vehicles.rs
+
+EXTRA_DIST = \
+ Vehicles.thrift
diff --git a/lib/rs/test_recursive/src/Vehicles.thrift b/lib/rs/test_recursive/src/Vehicles.thrift
new file mode 100644
index 000000000..5cce21cf4
--- /dev/null
+++ b/lib/rs/test_recursive/src/Vehicles.thrift
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+typedef i16 Capacity
+
+enum Material {
+ Steel = 0
+ Aluminum = 1
+}
+
+struct VehicleIdentifier {
+ 1: string manufacturer
+ 2: string model
+ 3: list<string> qualifiers
+}
diff --git a/lib/rs/test_recursive/src/lib.rs b/lib/rs/test_recursive/src/lib.rs
new file mode 100644
index 000000000..bac37b4de
--- /dev/null
+++ b/lib/rs/test_recursive/src/lib.rs
@@ -0,0 +1,276 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#![allow(dead_code)]
+
+pub mod transit;
+pub mod vehicles;
+pub mod maintenance;
+
+mod server {
+ use crate::maintenance::maintenance_facility::{
+ BigBarnSyncHandler, MultimodalFacilitySyncHandler,
+ };
+ use crate::transit::buses::{Bus, GarageSyncHandler};
+ use crate::transit::buses::{Powertrain, Route as BusRoute};
+ use crate::transit::light::streetcars::{
+ BarnSyncHandler, Flexity, RollingStock, Route, RouteNumber, Streetcar,
+ };
+ use crate::transit::services::city_services::TransitImprovements;
+ use crate::transit::trains::Locomotive;
+ use crate::transit::transporters::{FlatcarConsist, SingleVehicleTransporter};
+ use crate::vehicles::Material;
+ use thrift::Result;
+
+ //
+ // implement a whole bunch of handler methods just to make sure I can, and that everything compiles
+ //
+
+ pub struct AllInOneHandler;
+
+ impl BigBarnSyncHandler for AllInOneHandler {
+ fn handle_add_streetcar(&self, route: Route) -> Result<Streetcar> {
+ if let Some(route_number) = route.id {
+ match route_number {
+ RouteNumber::LAKESHORE => Ok(Streetcar {
+ id: Some(4417),
+ stock: Some(RollingStock::Flexity(Flexity {
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+ })),
+ route: Some(Route {
+ id: Some(RouteNumber::LAKESHORE),
+ improvements: None,
+ }),
+ }),
+ _ => Err(thrift::Error::from(format!(
+ "Cannot create streetcar for route number {}",
+ route_number.0
+ ))),
+ }
+ } else {
+ Err(thrift::Error::from("Can't add a streetcar"))
+ }
+ }
+ }
+
+ impl BarnSyncHandler for AllInOneHandler {
+ fn handle_upgrade_streetcar(&self, streetcar: Streetcar) -> Result<Streetcar> {
+ if let Some(rolling_stock) = streetcar.stock {
+ match rolling_stock {
+ RollingStock::Clrv(_) => Ok(Streetcar {
+ stock: Some(RollingStock::Flexity(Flexity {
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+ })),
+ ..streetcar
+ }),
+ RollingStock::Flexity(_) => {
+ Err(thrift::Error::from("Streetcar already upgraded"))
+ }
+ }
+ } else {
+ Err(thrift::Error::from("Can't upgrade streetcar"))
+ }
+ }
+ }
+
+ impl MultimodalFacilitySyncHandler for AllInOneHandler {
+ fn handle_build_transporter(
+ &self,
+ source: String,
+ destination: String,
+ consist: FlatcarConsist,
+ ) -> Result<SingleVehicleTransporter> {
+ Ok(SingleVehicleTransporter {
+ consist: Some(consist),
+ source: Some(source),
+ destination: Some(destination),
+ })
+ }
+ }
+
+ impl GarageSyncHandler for AllInOneHandler {
+ fn handle_upgrade_bus(&self, bus: Bus) -> Result<Bus> {
+ if let Some(p) = bus.powertrain {
+ match p {
+ Powertrain::COMPRESSED_NATURAL_GAS => Ok(Bus {
+ powertrain: Some(Powertrain::DIESEL),
+ ..bus
+ }),
+ _ => Err(thrift::Error::from("Cannot upgrade from this powertrain")),
+ }
+ } else {
+ Err(thrift::Error::from("Cannot upgrade bus"))
+ }
+ }
+
+ fn handle_improvements_for_route(
+ &self,
+ route: BusRoute,
+ ) -> Result<Vec<TransitImprovements>> {
+ Ok(route
+ .improvements
+ .expect("Expecting a list of improvements"))
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+
+ //
+ // TODO: consider using the generated client/server and doing a round-trip
+ //
+
+ use crate::server::AllInOneHandler;
+ use crate::transit::buses::{Bus, Powertrain, Route as BusRoute, DEFAULT4WHEELCAPACITY};
+ use crate::transit::light::light_rail::Lrt;
+ use crate::transit::light::streetcars::{
+ BarnSyncHandler, Flexity, RollingStock, Route, RouteNumber, Streetcar, CLRV,
+ };
+ use crate::transit::services::city_services::TransitImprovements;
+ use crate::transit::trains::Locomotive;
+ use crate::transit::transporters::{FlatcarConsist, SingleVehicleTransporter};
+ use crate::vehicles::{Material, VehicleIdentifier};
+
+ use crate::maintenance::maintenance_facility::{
+ BigBarnSyncHandler, MultimodalFacilitySyncHandler,
+ };
+ use crate::transit::buses::GarageSyncHandler;
+
+ #[test]
+ fn handle_add_streetcar_compiles_and_returns_expected_value() {
+ let expected = Streetcar {
+ id: Some(4417),
+ stock: Some(RollingStock::Flexity(Flexity {
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+ })),
+ route: Some(Route {
+ id: Some(RouteNumber::LAKESHORE),
+ improvements: None,
+ }),
+ };
+
+ let handler = AllInOneHandler {};
+ let actual = handler
+ .handle_add_streetcar(Route {
+ id: Some(RouteNumber::LAKESHORE),
+ improvements: None,
+ })
+ .expect("Expected a result");
+
+ assert_eq!(expected, actual)
+ }
+
+ #[test]
+ fn handle_upgrade_streetcar_compiles_and_returns_expected_value() {
+ let input = Streetcar {
+ stock: Some(RollingStock::Clrv(CLRV {
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ locomotive: Some(Locomotive::ELECTRIC_POLE),
+ })),
+ id: Some(4415),
+ route: Some(Route {
+ id: Some(RouteNumber::SPADINA),
+ improvements: Some(vec![TransitImprovements::DEDICATED_RIGHT_OF_WAY]),
+ }),
+ };
+
+ let expected = Streetcar {
+ stock: Some(RollingStock::Flexity(Flexity {
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+ })),
+ id: Some(4415),
+ route: Some(Route {
+ id: Some(RouteNumber::SPADINA),
+ improvements: Some(vec![TransitImprovements::DEDICATED_RIGHT_OF_WAY]),
+ }),
+ };
+
+ let handler = AllInOneHandler {};
+ let actual = handler
+ .handle_upgrade_streetcar(input)
+ .expect("Expected an upgraded streetcar");
+
+ assert_eq!(expected, actual)
+ }
+
+ #[test]
+ fn handle_build_transporter_compiles_and_returns_expected_value() {
+ let consist = FlatcarConsist::Lrt(Lrt {
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+ });
+ let expected = SingleVehicleTransporter {
+ consist: Some(consist.clone()),
+ source: Some("905".to_owned()),
+ destination: Some("416".to_owned()),
+ };
+
+ let handler = AllInOneHandler {};
+ let actual = handler
+ .handle_build_transporter("905".to_owned(), "416".to_owned(), consist)
+ .expect("Expected a transporter");
+
+ assert_eq!(expected, actual)
+ }
+
+ #[test]
+ fn handle_upgrade_bus_compiles_and_returns_expected_value() {
+ let bus = Bus {
+ identifier: Some(VehicleIdentifier {
+ manufacturer: Some("Orion".to_owned()),
+ model: Some("Orion 07.501 NG HEV".to_owned()),
+ qualifiers: None,
+ }),
+ capacity: Some(DEFAULT4WHEELCAPACITY),
+ powertrain: Some(Powertrain::COMPRESSED_NATURAL_GAS),
+ materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+ };
+
+ let expected = Bus {
+ powertrain: Some(Powertrain::DIESEL),
+ ..(bus.clone())
+ };
+
+ let handler = AllInOneHandler {};
+ let actual = handler
+ .handle_upgrade_bus(bus)
+ .expect("Expected improved bus");
+
+ assert_eq!(expected, actual)
+ }
+
+ #[test]
+ fn handle_improvements_for_route_compiles_and_returns_expected_value() {
+ let expected = vec![TransitImprovements::TRANSIT_SIGNAL_PRIORITY];
+ let bus_route = BusRoute {
+ route_id: Some("320".to_owned()),
+ improvements: Some(expected.clone()),
+ };
+
+ let handler = AllInOneHandler {};
+ let actual = handler
+ .handle_improvements_for_route(bus_route)
+ .expect("Expected list of transit improvements");
+
+ assert_eq!(expected, actual)
+ }
+}
diff --git a/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift b/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift
new file mode 100644
index 000000000..bed0b8dd9
--- /dev/null
+++ b/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs maintenance
+
+include "Buses.thrift"
+include "LightRail.thrift"
+include "Streetcars.thrift"
+include "Transporters.thrift"
+
+service BigBarn extends Streetcars.Barn {
+ Streetcars.Streetcar addStreetcar(1: Streetcars.Route route)
+}
+
+service MultimodalFacility extends Buses.Garage {
+ Transporters.SingleVehicleTransporter buildTransporter(1: string source, 2: string destination, 3: Transporters.FlatcarConsist consist)
+} \ No newline at end of file
diff --git a/lib/rs/test_recursive/src/maintenance/Makefile.am b/lib/rs/test_recursive/src/maintenance/Makefile.am
new file mode 100644
index 000000000..c24813a12
--- /dev/null
+++ b/lib/rs/test_recursive/src/maintenance/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+SUBDIRS = .
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+stubs: ../Vehicles.thrift ../transit/Buses.thrift ../transit/Trains.thrift ../transit/Transporters.thrift ../transit/services/CityServices.thrift ../transit/light/LightRail.thrift ../transit/light/Streetcars.thrift $(THRIFT)
+ $(THRIFT) -I . -I ../ -I ../transit -I ../transit/services -I ../transit/light -out . --gen rs MaintenanceFacility.thrift
+
+check: stubs
+
+clean-local:
+ -$(RM) maintenance_facility.rs
+
+EXTRA_DIST = \
+ MaintenanceFacility.thrift
diff --git a/lib/rs/test_recursive/src/maintenance/mod.rs b/lib/rs/test_recursive/src/maintenance/mod.rs
new file mode 100644
index 000000000..a75b6e1a5
--- /dev/null
+++ b/lib/rs/test_recursive/src/maintenance/mod.rs
@@ -0,0 +1,18 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+pub mod maintenance_facility;
diff --git a/lib/rs/test_recursive/src/transit/Buses.thrift b/lib/rs/test_recursive/src/transit/Buses.thrift
new file mode 100644
index 000000000..29dc5fecc
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/Buses.thrift
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs transit
+
+include "CityServices.thrift"
+include "Vehicles.thrift"
+
+const Vehicles.Capacity DEFAULT4WHEELCAPACITY = 30
+
+enum Powertrain {
+ DIESEL = 0
+ BIO_DIESEL = 1
+ COMPRESSED_NATURAL_GAS = 2
+ TROLLEY = 3
+ HYBRID = 4
+ BATTERY = 5
+}
+
+struct Bus {
+ 1: Vehicles.VehicleIdentifier identifier
+ 2: Vehicles.Capacity capacity
+ 3: Powertrain powertrain
+ 4: list<Vehicles.Material> materials
+}
+
+struct Route {
+ 1: string routeId
+ 2: list<CityServices.TransitImprovements> improvements
+}
+
+service Garage {
+ Bus upgradeBus(1: Bus bus)
+
+ list<CityServices.TransitImprovements> improvementsForRoute(1: Route route)
+} \ No newline at end of file
diff --git a/lib/rs/test_recursive/src/transit/Makefile.am b/lib/rs/test_recursive/src/transit/Makefile.am
new file mode 100644
index 000000000..731826546
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/Makefile.am
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# intentionally added a cyclic dependency between '.' and 'light'
+SUBDIRS = . light services
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+stubs: ../Vehicles.thrift Buses.thrift Trains.thrift Transporters.thrift services/CityServices.thrift light/LightRail.thrift light/Streetcars.thrift $(THRIFT)
+ $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Buses.thrift
+ $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Trains.thrift
+ $(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Transporters.thrift
+
+check: stubs
+
+clean-local:
+ -$(RM) buses.rs
+ -$(RM) trains.rs
+ -$(RM) transporters.rs
+
+EXTRA_DIST = \
+ Buses.thrift \
+ Trains.thrift \
+ Transporters.thrift
diff --git a/lib/rs/test_recursive/src/transit/Trains.thrift b/lib/rs/test_recursive/src/transit/Trains.thrift
new file mode 100644
index 000000000..6f97b53c8
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/Trains.thrift
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs transit
+
+enum Locomotive {
+ Steam = 0
+ ElectricPole = 1
+ ElectricPantograph = 2
+ ElectricThirdRail = 3
+ DieselMechanical = 4
+ DieselElectric = 5
+}
diff --git a/lib/rs/test_recursive/src/transit/Transporters.thrift b/lib/rs/test_recursive/src/transit/Transporters.thrift
new file mode 100644
index 000000000..540f1bb38
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/Transporters.thrift
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs transit
+
+include "Buses.thrift"
+include "LightRail.thrift"
+include "Streetcars.thrift"
+
+union FlatcarConsist {
+ 1: LightRail.Lrt lrt
+ 2: Streetcars.Streetcar streetcar
+ 3: Buses.Bus bus
+}
+
+struct SingleVehicleTransporter {
+ 1: FlatcarConsist consist
+ 2: string source
+ 3: string destination
+}
diff --git a/lib/rs/test_recursive/src/transit/light/LightRail.thrift b/lib/rs/test_recursive/src/transit/light/LightRail.thrift
new file mode 100644
index 000000000..0d887ab4d
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/light/LightRail.thrift
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+include "CityServices.thrift"
+include "Trains.thrift"
+include "Vehicles.thrift"
+
+namespace rs transit.light
+
+struct Lrt {
+ 1: list<Vehicles.Material> materials
+ 2: Trains.Locomotive locomotive
+}
+
+enum Route {
+ EglintonCrosstown = 0
+ FinchWest = 1
+}
+
+struct Line {
+ 1: Lrt lrt
+ 2: Route route
+ 3: list<CityServices.TransitImprovements> improvements = [] // ABSOLUTELY NONE BY DEFAULT!
+}
+
+service Msf {
+ Lrt fixLrt(1: Lrt lrt)
+} \ No newline at end of file
diff --git a/lib/rs/test_recursive/src/transit/light/Makefile.am b/lib/rs/test_recursive/src/transit/light/Makefile.am
new file mode 100644
index 000000000..c09c39d99
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/light/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+SUBDIRS = .
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+stubs: ../../Vehicles.thrift ../Trains.thrift ../services/CityServices.thrift LightRail.thrift Streetcars.thrift $(THRIFT)
+ $(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs LightRail.thrift
+ $(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs Streetcars.thrift
+
+check: stubs
+
+clean-local:
+ -$(RM) light_rail.rs
+ -$(RM) streetcars.rs
+
+EXTRA_DIST = \
+ LightRail.thrift \
+ Streetcars.thrift
diff --git a/lib/rs/test_recursive/src/transit/light/Streetcars.thrift b/lib/rs/test_recursive/src/transit/light/Streetcars.thrift
new file mode 100644
index 000000000..31d3ad47e
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/light/Streetcars.thrift
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+include "CityServices.thrift"
+include "Trains.thrift"
+include "Vehicles.thrift"
+
+namespace rs transit.light
+
+struct CLRV {
+ 1: list<Vehicles.Material> materials
+ 2: Trains.Locomotive locomotive
+}
+
+struct Flexity {
+ 1: list<Vehicles.Material> materials
+ 2: Trains.Locomotive locomotive
+}
+
+union RollingStock {
+ 1: CLRV clrv
+ 2: Flexity flexity
+}
+
+enum RouteNumber {
+ Queen = 501
+ Downtowner = 502
+ Kingston = 503
+ King = 504
+ Dundas = 505
+ Carlton = 506
+ Lakeshore = 508
+ Harbourfront = 509
+ Spadina = 510
+ Bathurst = 511
+ StClair = 512
+}
+
+struct Route {
+ 1: RouteNumber id
+ 2: list<CityServices.TransitImprovements> improvements = [] // ABSOLUTELY NONE!
+}
+
+struct Streetcar {
+ 1: i16 id
+ 2: RollingStock stock
+ 3: Route route
+}
+
+service Barn {
+ Streetcar upgradeStreetcar(1: Streetcar streetcar)
+} \ No newline at end of file
diff --git a/lib/rs/test_recursive/src/transit/light/mod.rs b/lib/rs/test_recursive/src/transit/light/mod.rs
new file mode 100644
index 000000000..f68d0990d
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/light/mod.rs
@@ -0,0 +1,19 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+pub mod light_rail;
+pub mod streetcars;
diff --git a/lib/rs/test_recursive/src/transit/mod.rs b/lib/rs/test_recursive/src/transit/mod.rs
new file mode 100644
index 000000000..e144b3823
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/mod.rs
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+pub mod buses;
+pub mod light;
+pub mod services;
+pub mod trains;
+pub mod transporters;
diff --git a/lib/rs/test_recursive/src/transit/services/CityServices.thrift b/lib/rs/test_recursive/src/transit/services/CityServices.thrift
new file mode 100644
index 000000000..2ca559add
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/services/CityServices.thrift
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs transit.services
+
+enum TransitImprovements {
+ TransitSignalPriority = 1
+ DedicatedRightOfWay = 2
+}
diff --git a/lib/rs/test_recursive/src/transit/services/Makefile.am b/lib/rs/test_recursive/src/transit/services/Makefile.am
new file mode 100644
index 000000000..f70e9198d
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/services/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+SUBDIRS = .
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+stubs: CityServices.thrift $(THRIFT)
+ $(THRIFT) -I . -out . --gen rs CityServices.thrift
+
+check: stubs
+
+clean-local:
+ -$(RM) city_services.rs
+
+EXTRA_DIST = \
+ CityServices.thrift
diff --git a/lib/rs/test_recursive/src/transit/services/mod.rs b/lib/rs/test_recursive/src/transit/services/mod.rs
new file mode 100644
index 000000000..2cb171aa2
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/services/mod.rs
@@ -0,0 +1,18 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+pub mod city_services;