diff --git a/compiler/cpp/CMakeLists.txt b/compiler/cpp/CMakeLists.txt
index 9f7585d..8e861e4 100644
--- a/compiler/cpp/CMakeLists.txt
+++ b/compiler/cpp/CMakeLists.txt
@@ -101,6 +101,7 @@
 THRIFT_ADD_COMPILER(d       "Enable compiler for D" ON)
 THRIFT_ADD_COMPILER(lua     "Enable compiler for Lua" ON)
 THRIFT_ADD_COMPILER(gv      "Enable compiler for GraphViz" ON)
+THRIFT_ADD_COMPILER(rs      "Enable compiler for Rust" ON)
 THRIFT_ADD_COMPILER(xml     "Enable compiler for XML" ON)
 
 # Thrift is looking for include files in the src directory
diff --git a/compiler/cpp/Makefile.am b/compiler/cpp/Makefile.am
index 5d424b4..5082033 100644
--- a/compiler/cpp/Makefile.am
+++ b/compiler/cpp/Makefile.am
@@ -107,7 +107,8 @@
                   src/thrift/generate/t_go_generator.cc \
                   src/thrift/generate/t_gv_generator.cc \
                   src/thrift/generate/t_d_generator.cc \
-                  src/thrift/generate/t_lua_generator.cc
+                  src/thrift/generate/t_lua_generator.cc \
+                  src/thrift/generate/t_rs_generator.cc
 
 thrift_CPPFLAGS = -I$(srcdir)/src
 thrift_CXXFLAGS = -Wall -Wextra -pedantic
diff --git a/compiler/cpp/compiler.vcxproj b/compiler/cpp/compiler.vcxproj
index 1e86360..4b03253 100644
--- a/compiler/cpp/compiler.vcxproj
+++ b/compiler/cpp/compiler.vcxproj
@@ -79,6 +79,7 @@
     <ClCompile Include="src\thrift\generate\t_php_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_py_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_rb_generator.cc" />
+    <ClCompile Include="src\thrift\generate\t_rs_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_st_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_swift_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_xml_generator.cc" />
diff --git a/compiler/cpp/compiler.vcxproj.filters b/compiler/cpp/compiler.vcxproj.filters
index 9b14bbf..b96865b 100644
--- a/compiler/cpp/compiler.vcxproj.filters
+++ b/compiler/cpp/compiler.vcxproj.filters
@@ -161,6 +161,9 @@
     <ClCompile Include="src\generate\t_rb_generator.cc">
       <Filter>generate</Filter>
     </ClCompile>
+    <ClCompile Include="src\generate\t_rs_generator.cc">
+      <Filter>generate</Filter>
+    </ClCompile>
     <ClCompile Include="src\generate\t_st_generator.cc">
       <Filter>generate</Filter>
     </ClCompile>
@@ -193,4 +196,4 @@
     <None Include="src\thriftl.ll" />
     <None Include="src\thrifty.yy" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
new file mode 100644
index 0000000..5cd304b
--- /dev/null
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -0,0 +1,3164 @@
+/*
+ * 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.
+ */
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "thrift/platform.h"
+#include "thrift/generate/t_generator.h"
+
+using std::map;
+using std::ofstream;
+using std::ostringstream;
+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";
+static const string RESULT_STRUCT_SUFFIX = "Result";
+static const string RUST_RESERVED_WORDS[] = {
+  "abstract", "alignof", "as", "become",
+  "box", "break", "const", "continue",
+  "crate", "do", "else", "enum",
+  "extern", "false", "final", "fn",
+  "for", "if", "impl", "in",
+  "let", "loop", "macro", "match",
+  "mod", "move", "mut", "offsetof",
+  "override", "priv", "proc", "pub",
+  "pure", "ref", "return", "Self",
+  "self", "sizeof", "static", "struct",
+  "super", "trait", "true", "type",
+  "typeof", "unsafe", "unsized", "use",
+  "virtual", "where", "while", "yield"
+};
+const set<string> RUST_RESERVED_WORDS_SET(
+  RUST_RESERVED_WORDS,
+  RUST_RESERVED_WORDS + sizeof(RUST_RESERVED_WORDS)/sizeof(RUST_RESERVED_WORDS[0])
+);
+
+// FIXME: extract common TMessageIdentifier function
+// FIXME: have to_rust_type deal with Option
+
+class t_rs_generator : public t_generator {
+public:
+  t_rs_generator(
+    t_program* program,
+    const std::map<std::string, std::string>&,
+    const std::string&
+  ) : t_generator(program) {
+    gen_dir_ = get_out_dir();
+  }
+
+  /**
+   * Init and close methods
+   */
+
+  void init_generator();
+  void close_generator();
+
+  /**
+   * Program-level generation functions
+   */
+
+  void generate_typedef(t_typedef* ttypedef);
+  void generate_enum(t_enum* tenum);
+  void generate_const(t_const* tconst);
+  void generate_struct(t_struct* tstruct);
+  void generate_xception(t_struct* txception);
+  void generate_service(t_service* tservice);
+
+private:
+  // struct type
+  // T_REGULAR: user-defined struct in the IDL
+  // T_ARGS: struct used to hold all service-call parameters
+  // T_RESULT: struct used to hold all service-call returns and exceptions
+  // T_EXCEPTION: user-defined exception in the IDL
+  enum e_struct_type { T_REGULAR, T_ARGS, T_RESULT, T_EXCEPTION };
+
+  // Directory to which generated code is written.
+  string gen_dir_;
+
+  // File to which generated code is written.
+  std::ofstream f_gen_;
+
+  // Write the common compiler attributes and module includes to the top of the auto-generated file.
+  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);
+
+  // Write the rust representation of an enum.
+  void render_enum_definition(t_enum* tenum, const string& enum_name);
+
+  // Write the impl blocks associated with the traits necessary to convert an enum to/from an i32.
+  void render_enum_conversion(t_enum* tenum, const string& enum_name);
+
+  // Write the impl block associated with the rust representation of an enum. This includes methods
+  // to write the enum to a protocol, read it from a protocol, etc.
+  void render_enum_impl(const string& enum_name);
+
+  // Write a simple rust const value (ie. `pub const FOO: foo...`).
+  void render_const_value(const string& name, t_type* ttype, t_const_value* tvalue);
+
+  // Write a constant list, set, map or struct. These constants require allocation and cannot be defined
+  // using a 'pub const'. As a result, I create a holder struct with a single `const_value` method that
+  // returns the initialized instance.
+  void render_const_value_holder(const string& name, t_type* ttype, t_const_value* tvalue);
+
+  // Write the actual const value - the right side of a const definition.
+  void render_const_value(t_type* ttype, t_const_value* tvalue);
+
+  // Write a const struct (returned from `const_value` method).
+  void render_const_struct(t_type* ttype, t_const_value* tvalue);
+
+  // Write a const list (returned from `const_value` method).
+  void render_const_list(t_type* ttype, t_const_value* tvalue);
+
+  // Write a const set (returned from `const_value` method).
+  void render_const_set(t_type* ttype, t_const_value* tvalue);
+
+  // Write a const map (returned from `const_value` method).
+  void render_const_map(t_type* ttype, t_const_value* tvalue);
+
+  // Write the code to insert constant values into a rust vec or set. The
+  // `insert_function` is the rust function that we'll use to insert the elements.
+  void render_container_const_value(
+    const string& insert_function,
+    t_type* ttype,
+    t_const_value* tvalue
+  );
+
+  // Write the rust representation of a thrift struct to the generated file. Set `struct_type` to `T_ARGS`
+  // if rendering the struct used to pack arguments for a service call. When `struct_type` is `T_ARGS` the
+  // struct and its members have module visibility, and all fields are required. When `struct_type` is
+  // anything else the struct and its members have public visibility and fields have the visibility set
+  // in their definition.
+  void render_struct(const string& struct_name, t_struct* tstruct, t_rs_generator::e_struct_type struct_type);
+
+  // Write the comment block preceding a type definition (and implementation).
+  void render_type_comment(const string& struct_name);
+
+  // Write the rust representation of a thrift struct. Supports argument structs, result structs,
+  // user-defined structs and exception structs. The exact struct type to be generated is controlled
+  // by the `struct_type` parameter, which (among other things) modifies the visibility of the
+  // written struct and members, controls which trait implementations are generated.
+  void render_struct_definition(
+    const string& struct_name,
+    t_struct* tstruct,
+    t_rs_generator::e_struct_type struct_type
+  );
+
+  // Writes the impl block associated with the rust representation of a struct. At minimum this
+  // contains the methods to read from a protocol and write to a protocol. Additional methods may
+  // be generated depending on `struct_type`.
+  void render_struct_impl(
+    const string& struct_name,
+    t_struct* tstruct,
+    t_rs_generator::e_struct_type struct_type
+  );
+
+  // Generate a `fn new(...)` for a struct with name `struct_name` and type `t_struct`. The auto-generated
+  // code may include generic type parameters to make the constructor more ergonomic. `struct_type` controls
+  // the visibility of the generated constructor.
+  void render_struct_constructor(
+    const string& struct_name,
+    t_struct* tstruct,
+    t_rs_generator::e_struct_type struct_type
+  );
+
+  // Write the `ok_or` method added to all Thrift service call result structs. You can use this method
+  // to convert a struct into a `Result` and use it in a `try!` or combinator chain.
+  void render_result_struct_to_result_method(t_struct* tstruct);
+
+  // Write the implementations for the `Error` and `Debug` traits. These traits are necessary for a
+  // user-defined exception to be properly handled as Rust errors.
+  void render_exception_struct_error_trait_impls(const string& struct_name, t_struct* tstruct);
+
+  // Write the implementations for the `Default`. This trait allows you to specify only the fields you want
+  // and use `..Default::default()` to fill in the rest.
+  void render_struct_default_trait_impl(const string& struct_name, t_struct* tstruct);
+
+  // Write the function that serializes a struct to its wire representation. If `struct_type` is `T_ARGS`
+  // then all fields are considered "required", if not, the default optionality is used.
+  void render_struct_sync_write(t_struct *tstruct, t_rs_generator::e_struct_type struct_type);
+
+  // Helper function that serializes a single struct field to its wire representation. Unpacks the
+  // variable (since it may be optional) and serializes according to the optionality rules required by `req`.
+  // Variables in auto-generated code are passed by reference. Since this function may be called in
+  // contexts where the variable is *already* a reference you can set `field_var_is_ref` to `true` to avoid
+  // generating an extra, unnecessary `&` that the compiler will have to automatically dereference.
+  void render_struct_field_sync_write(
+    const string &field_var,
+    bool field_var_is_ref,
+    t_field *tfield,
+    t_field::e_req req);
+
+  // Write the rust function that serializes a single type (i.e. a i32 etc.) to its wire representation.
+  // Variables in auto-generated code are passed by reference. Since this function may be called in
+  // contexts where the variable is *already* a reference you can set `type_var_is_ref` to `true` to avoid
+  // generating an extra, unnecessary `&` that the compiler will have to automatically dereference.
+  void render_type_sync_write(const string &type_var, bool type_var_is_ref, t_type *ttype);
+
+  // Write a list to the output protocol. `list_variable` is the variable containing the list
+  // that will be written to the output protocol.
+  // Variables in auto-generated code are passed by reference. Since this function may be called in
+  // contexts where the variable is *already* a reference you can set `list_var_is_ref` to `true` to avoid
+  // generating an extra, unnecessary `&` that the compiler will have to automatically dereference.
+  void render_list_sync_write(const string &list_var, bool list_var_is_ref, t_list *tlist);
+
+  // Write a set to the output protocol. `set_variable` is the variable containing the set that will
+  // be written to the output protocol.
+  // Variables in auto-generated code are passed by reference. Since this function may be called in
+  // contexts where the variable is *already* a reference you can set `set_var_is_ref` to `true` to avoid
+  // generating an extra, unnecessary `&` that the compiler will have to automatically dereference.
+  void render_set_sync_write(const string &set_var, bool set_var_is_ref, t_set *tset);
+
+  // Write a map to the output protocol. `map_variable` is the variable containing the map that will
+  // be written to the output protocol.
+  // Variables in auto-generated code are passed by reference. Since this function may be called in
+  // contexts where the variable is *already* a reference you can set `map_var_is_ref` to `true` to avoid
+  // generating an extra, unnecessary `&` that the compiler will have to automatically dereference.
+  void render_map_sync_write(const string &map_var, bool map_var_is_ref, t_map *tset);
+
+  // Return `true` if we need to dereference ths type when writing an element from a container.
+  // Iterations on rust containers are performed as follows: `for v in &values { ... }`
+  // where `v` has type `&RUST_TYPE` All defined functions take primitives by value, so, if the
+  // rendered code is calling such a function it has to dereference `v`.
+  bool needs_deref_on_container_write(t_type* ttype);
+
+  // Write the code to read bytes from the wire into the given `t_struct`. `struct_name` is the
+  // actual Rust name of the `t_struct`. If `struct_type` is `T_ARGS` then all struct fields are
+  // necessary. Otherwise, the field's default optionality is used.
+  void render_struct_sync_read(const string &struct_name, t_struct *tstruct, t_rs_generator::e_struct_type struct_type);
+
+  // Write the rust function that deserializes a single type (i.e. i32 etc.) from its wire representation.
+  void render_type_sync_read(const string &type_var, t_type *ttype);
+
+  // Read the wire representation of a list and convert it to its corresponding rust implementation.
+  // The deserialized list is stored in `list_variable`.
+  void render_list_sync_read(t_list *tlist, const string &list_variable);
+
+  // Read the wire representation of a set and convert it to its corresponding rust implementation.
+  // The deserialized set is stored in `set_variable`.
+  void render_set_sync_read(t_set *tset, const string &set_variable);
+
+  // Read the wire representation of a map and convert it to its corresponding rust implementation.
+  // The deserialized map is stored in `map_variable`.
+  void render_map_sync_read(t_map *tmap, const string &map_variable);
+
+  // Return a temporary variable used to store values when deserializing nested containers.
+  string struct_field_read_temp_variable(t_field* tfield);
+
+  // Top-level function that calls the various render functions necessary to write the rust representation
+  // of a thrift union (i.e. an enum).
+  void render_union(t_struct* tstruct);
+
+  // Write the enum corresponding to the Thrift union.
+  void render_union_definition(const string& union_name, t_struct* tstruct);
+
+  // Write the enum impl (with read/write functions) for the Thrift union.
+  void render_union_impl(const string& union_name, t_struct* tstruct);
+
+  // Write the `ENUM::write_to_out_protocol` function.
+  void render_union_sync_write(const string &union_name, t_struct *tstruct);
+
+  // Write the `ENUM::read_from_in_protocol` function.
+  void render_union_sync_read(const string &union_name, t_struct *tstruct);
+
+  // Top-level function that calls the various render functions necessary to write the rust representation
+  // of a Thrift client.
+  void render_sync_client(t_service* tservice);
+
+  // Write the trait with the service-call methods for `tservice`.
+  void render_sync_client_trait(t_service *tservice);
+
+  // Write the trait to be implemented by the client impl if end users can use it to make service calls.
+  void render_sync_client_marker_trait(t_service *tservice);
+
+  // Write the code to create the Thrift service sync client struct and its matching 'impl' block.
+  void render_sync_client_definition_and_impl(const string& client_impl_name);
+
+  // Write the code to create the `SyncClient::new` functions as well as any other functions
+  // callers would like to use on the Thrift service sync client.
+  void render_sync_client_lifecycle_functions(const string& client_struct);
+
+  // Write the code to create the impl block for the `TThriftClient` trait. Since generated
+  // Rust Thrift clients perform all their operations using methods defined in this trait, we
+  // have to implement it for the client structs.
+  void render_sync_client_tthriftclient_impl(const string &client_impl_name);
+
+  // Write the marker traits for any service(s) being extended, including the one for the current
+  // service itself (i.e. `tservice`)
+  void render_sync_client_marker_trait_impls(t_service *tservice, const string &impl_struct_name);
+
+  // Generate a list of all the traits this Thrift client struct extends.
+  string sync_client_marker_traits_for_extension(t_service *tservice);
+
+  // Top-level function that writes the code to make the Thrift service calls.
+  void render_sync_client_process_impl(t_service* tservice);
+
+  // Write the actual function that calls out to the remote service and processes its response.
+  void render_sync_send_recv_wrapper(t_function* tfunc);
+
+  // Write the `send` functionality for a Thrift service call represented by a `t_service->t_function`.
+  void render_sync_send(t_function* tfunc);
+
+  // Write the `recv` functionality for a Thrift service call represented by a `t_service->t_function`.
+  // This method is only rendered if the function is *not* oneway.
+  void render_sync_recv(t_function* tfunc);
+
+  void render_sync_processor(t_service *tservice);
+
+  void render_sync_handler_trait(t_service *tservice);
+  void render_sync_processor_definition_and_impl(t_service *tservice);
+  void render_sync_process_delegation_functions(t_service *tservice);
+  void render_sync_process_function(t_function *tfunc, const string &handler_type);
+  void render_process_match_statements(t_service* tservice);
+  void render_sync_handler_succeeded(t_function *tfunc);
+  void render_sync_handler_failed(t_function *tfunc);
+  void render_sync_handler_failed_user_exception_branch(t_function *tfunc);
+  void render_sync_handler_failed_application_exception_branch(t_function *tfunc, const string &app_err_var);
+  void render_sync_handler_failed_default_exception_branch(t_function *tfunc);
+  void render_sync_handler_send_exception_response(t_function *tfunc, const string &err_var);
+  void render_service_call_structs(t_service* tservice);
+  void render_result_value_struct(t_function* tfunc);
+
+  string handler_successful_return_struct(t_function* tfunc);
+
+  void render_rift_error(
+    const string& error_kind,
+    const string& error_struct,
+    const string& sub_error_kind,
+    const string& error_message
+  );
+  void render_rift_error_struct(
+    const string& error_struct,
+    const string& sub_error_kind,
+    const string& error_message
+  );
+
+  // Return a string containing all the unpacked service call args given a service call function
+  // `t_function`. Prepends the args with `&mut self` and includes the arg types in the returned string,
+  // for example: `fn foo(&mut self, field_0: String)`.
+  string rust_sync_service_call_declaration(t_function* tfunc);
+
+  // Return a string containing all the unpacked service call args given a service call function
+  // `t_function`. Only includes the arg names, each of which is prefixed with the optional prefix
+  // `field_prefix`, for example: `self.field_0`.
+  string rust_sync_service_call_invocation(t_function* tfunc, const string& field_prefix = "");
+
+  // Return a string containing all fields in the struct `tstruct` for use in a function declaration.
+  // Each field is followed by its type, for example: `field_0: String`.
+  string struct_to_declaration(t_struct* tstruct, t_rs_generator::e_struct_type struct_type);
+
+  // Return a string containing all fields in the struct `tstruct` for use in a function call,
+  // for example: `field_0: String`.
+  string struct_to_invocation(t_struct* tstruct, const string& field_prefix = "");
+
+  // Write the documentation for a struct, service-call or other documentation-annotated element.
+  void render_rustdoc(t_doc* tdoc);
+
+  // Return a string representing the rust type given a `t_type`.
+  string to_rust_type(t_type* ttype, bool ordered_float = true);
+
+  // Return a string representing the rift `protocol::TType` given a `t_type`.
+  string to_rust_field_type_enum(t_type* ttype);
+
+  // Return the default value to be used when initializing a struct field which has `OPT_IN_REQ_OUT`
+  // optionality.
+  string opt_in_req_out_value(t_type* ttype);
+
+  // Return `true` if we can write a const of the form `pub const FOO: ...`.
+  bool can_generate_simple_const(t_type* ttype);
+
+  // Return `true` if we cannot write a standard Rust constant (because the type needs some allocation).
+  bool can_generate_const_holder(t_type* ttype);
+
+  // Return `true` if this type is a void, and should be represented by the rust `()` type.
+  bool is_void(t_type* ttype);
+
+  t_field::e_req actual_field_req(t_field* tfield, t_rs_generator::e_struct_type struct_type);
+
+  // Return `true` if this `t_field::e_req` is either `t_field::T_OPTIONAL` or `t_field::T_OPT_IN_REQ_OUT`
+  // and needs to be wrapped by an `Option<TYPE_NAME>`, `false` otherwise.
+  bool is_optional(t_field::e_req req);
+
+  // Return `true` if the service call has arguments, `false` otherwise.
+  bool has_args(t_function* tfunc);
+
+  // Return `true` if a service call has non-`()` arguments, `false` otherwise.
+  bool has_non_void_args(t_function* tfunc);
+
+  // Return `pub ` (notice trailing whitespace!) if the struct should be public, `` (empty string) otherwise.
+  string visibility_qualifier(t_rs_generator::e_struct_type struct_type);
+
+  // Returns the namespace prefix for a given Thrift service. If the type is defined in the presently-computed
+  // Thrift program, then an empty string is returned.
+  string rust_namespace(t_service* tservice);
+
+  // Returns the namespace prefix for a given Thrift type. If the type is defined in the presently-computed
+  // Thrift program, then an empty string is returned.
+  string rust_namespace(t_type* ttype);
+
+  // Returns the camel-cased name for a Rust struct type. Handles the case where `tstruct->get_name()` is
+  // a reserved word.
+  string rust_struct_name(t_struct* tstruct);
+
+  // Returns the snake-cased name for a Rust field or local variable. Handles the case where
+  // `tfield->get_name()` is a reserved word.
+  string rust_field_name(t_field* tstruct);
+
+  // Returns the camel-cased name for a Rust union type. Handles the case where `tstruct->get_name()` is
+  // a reserved word.
+  string rust_union_field_name(t_field* tstruct);
+
+  // Converts any variable name into a 'safe' variant that does not clash with any Rust reserved keywords.
+  string rust_safe_name(const string& name);
+
+  // Return `true` if the name is a reserved Rust keyword, `false` otherwise.
+  bool is_reserved(const string& name);
+
+  // Return the name of the function that users will invoke to make outgoing service calls.
+  string service_call_client_function_name(t_function* tfunc);
+
+  // Return the name of the function that users will have to implement to handle incoming service calls.
+  string service_call_handler_function_name(t_function* tfunc);
+
+  // Return the name of the struct used to pack the return value
+  // and user-defined exceptions for the thrift service call.
+  string service_call_result_struct_name(t_function* tfunc);
+
+  string rust_sync_client_marker_trait_name(t_service* tservice);
+
+  // Return the trait name for the sync service client given a `t_service`.
+  string rust_sync_client_trait_name(t_service* tservice);
+
+  // Return the name for the sync service client struct given a `t_service`.
+  string rust_sync_client_impl_name(t_service* tservice);
+
+  // Return the trait name that users will have to implement for the server half of a Thrift service.
+  string rust_sync_handler_trait_name(t_service* tservice);
+
+  // Return the struct name for the  server half of a Thrift service.
+  string rust_sync_processor_name(t_service* tservice);
+
+  // Return the struct name for the struct that contains all the service-call implementations for
+  // the server half of a Thrift service.
+  string rust_sync_processor_impl_name(t_service *tservice);
+
+  // Properly uppercase names for use in Rust.
+  string rust_upper_case(const string& name);
+
+  // Snake-case field, parameter and function names and make them Rust friendly.
+  string rust_snake_case(const string& name);
+
+  // Camel-case type/variant names and make them Rust friendly.
+  string rust_camel_case(const string& name);
+
+  // Replace all instances of `search_string` with `replace_string` in `target`.
+  void string_replace(string& target, const string& search_string, const string& replace_string);
+};
+
+void t_rs_generator::init_generator() {
+  // make output directory for this thrift program
+  MKDIR(gen_dir_.c_str());
+
+  // create the file into which we're going to write the generated code
+  string f_gen_name = gen_dir_ + "/" + rust_snake_case(get_program()->get_name()) + ".rs";
+  f_gen_.open(f_gen_name.c_str());
+
+  // header comment
+  f_gen_ << "// " << autogen_summary() << endl;
+  f_gen_ << "// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING" << endl;
+  f_gen_ << endl;
+
+  render_attributes_and_includes();
+}
+
+void t_rs_generator::render_attributes_and_includes() {
+  // turn off some compiler/clippy warnings
+
+  // code always includes BTreeMap/BTreeSet/OrderedFloat
+  f_gen_ << "#![allow(unused_imports)]" << endl;
+  // constructors take *all* struct parameters, which can trigger the "too many arguments" warning
+  // some auto-gen'd types can be deeply nested. clippy recommends factoring them out which is hard to autogen
+  f_gen_ << "#![cfg_attr(feature = \"cargo-clippy\", allow(too_many_arguments, type_complexity))]" << endl;
+  f_gen_ << endl;
+
+  // add standard includes
+  f_gen_ << "extern crate ordered_float;" << endl;
+  f_gen_ << "extern crate thrift;" << endl;
+  f_gen_ << "extern crate try_from;" << endl;
+  f_gen_ << endl;
+  f_gen_ << "use ordered_float::OrderedFloat;" << endl;
+  f_gen_ << "use std::cell::RefCell;" << endl;
+  f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << endl;
+  f_gen_ << "use std::convert::From;" << endl;
+  f_gen_ << "use std::default::Default;" << endl;
+  f_gen_ << "use std::error::Error;" << endl;
+  f_gen_ << "use std::fmt;" << endl;
+  f_gen_ << "use std::fmt::{Display, Formatter};" << endl;
+  f_gen_ << "use std::rc::Rc;" << endl;
+  f_gen_ << "use try_from::TryFrom;" << endl;
+  f_gen_ << endl;
+  f_gen_ << "use thrift::{ApplicationError, ApplicationErrorKind, ProtocolError, ProtocolErrorKind, TThriftClient};" << endl;
+  f_gen_ << "use thrift::protocol::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, TInputProtocol, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType};" << endl;
+  f_gen_ << "use thrift::protocol::field_id;" << endl;
+  f_gen_ << "use thrift::protocol::verify_expected_message_type;" << endl;
+  f_gen_ << "use thrift::protocol::verify_expected_sequence_number;" << endl;
+  f_gen_ << "use thrift::protocol::verify_expected_service_call;" << endl;
+  f_gen_ << "use thrift::protocol::verify_required_field_exists;" << endl;
+  f_gen_ << "use thrift::server::TProcessor;" << endl;
+  f_gen_ << endl;
+
+  // add all the program 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;
+
+  // 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());
+  }
+
+  // next, recursively iterate through all the services and add the names of any programs they reference
+  const vector<t_service*> services = get_program()->get_services();
+  vector<t_service*>::const_iterator service_iter;
+  for (service_iter = services.begin(); service_iter != services.end(); ++service_iter) {
+    compute_service_referenced_modules(*service_iter, referenced_modules);
+  }
+
+  // finally, write all the "pub use..." declarations
+  if (!referenced_modules.empty()) {
+    set<string>::iterator module_iter;
+    for (module_iter = referenced_modules.begin(); module_iter != referenced_modules.end(); ++module_iter) {
+      f_gen_ << "use " << rust_snake_case(*module_iter) << ";" << endl;
+    }
+    f_gen_ << endl;
+  }
+}
+
+void t_rs_generator::compute_service_referenced_modules(
+  t_service *tservice,
+  set<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());
+    }
+    compute_service_referenced_modules(extends, referenced_modules);
+  }
+}
+
+void t_rs_generator::close_generator() {
+  f_gen_.close();
+}
+
+//-----------------------------------------------------------------------------
+//
+// Consts
+//
+// NOTE: consider using macros to generate constants
+//
+//-----------------------------------------------------------------------------
+
+// This is worse than it should be because constants
+// aren't (sensibly) limited to scalar types
+void t_rs_generator::generate_const(t_const* tconst) {
+  string name = tconst->get_name();
+  t_type* ttype = tconst->get_type();
+  t_const_value* tvalue = tconst->get_value();
+
+  if (can_generate_simple_const(ttype)) {
+    render_const_value(name, ttype, tvalue);
+  } else if (can_generate_const_holder(ttype)) {
+    render_const_value_holder(name, ttype, tvalue);
+  } else {
+    throw "cannot generate const for " + name;
+  }
+}
+
+void t_rs_generator::render_const_value(const string& name, t_type* ttype, t_const_value* tvalue) {
+  if (!can_generate_simple_const(ttype)) {
+    throw "cannot generate simple rust constant for " + ttype->get_name();
+  }
+
+  f_gen_ << "pub const " << rust_upper_case(name) << ": " << to_rust_type(ttype) << " = ";
+  render_const_value(ttype, tvalue);
+  f_gen_ << ";" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_const_value_holder(const string& name, t_type* ttype, t_const_value* tvalue) {
+  if (!can_generate_const_holder(ttype)) {
+    throw "cannot generate constant holder for " + ttype->get_name();
+  }
+
+  string holder_name("Const" + rust_camel_case(name));
+
+  f_gen_ << indent() << "pub struct " << holder_name << ";" << endl;
+  f_gen_ << indent() << "impl " << holder_name << " {" << endl;
+  indent_up();
+
+  f_gen_ << indent() << "pub fn const_value() -> " << to_rust_type(ttype) << " {" << endl;
+  indent_up();
+  render_const_value(ttype, tvalue);
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_const_value(t_type* ttype, t_const_value* tvalue) {
+  if (ttype->is_base_type()) {
+    t_base_type* tbase_type = (t_base_type*)ttype;
+    switch (tbase_type->get_base()) {
+    case t_base_type::TYPE_STRING:
+      if (tbase_type->is_binary()) {
+        f_gen_ << "\"" << tvalue->get_string() << "\""<<  ".to_owned().into_bytes()";
+      } else {
+        f_gen_ << "\"" << tvalue->get_string() << "\""<<  ".to_owned()";
+      }
+      break;
+    case t_base_type::TYPE_BOOL:
+      f_gen_ << (tvalue->get_integer() ? "true" : "false");
+      break;
+    case t_base_type::TYPE_I8:
+    case t_base_type::TYPE_I16:
+    case t_base_type::TYPE_I32:
+    case t_base_type::TYPE_I64:
+      f_gen_ << tvalue->get_integer();
+      break;
+    case t_base_type::TYPE_DOUBLE:
+      f_gen_
+        << indent()
+        << "OrderedFloat::from(" << tvalue->get_double() << ")"
+        << endl;
+      break;
+    default:
+      throw "cannot generate const value for " + t_base_type::t_base_name(tbase_type->get_base());
+    }
+  } else if (ttype->is_typedef()) {
+    render_const_value(get_true_type(ttype), tvalue);
+  } else if (ttype->is_enum()) {
+    f_gen_ << indent() << "{" << endl;
+    indent_up();
+    f_gen_
+      << indent()
+      << to_rust_type(ttype)
+      << "::try_from("
+      << tvalue->get_integer()
+      << ").expect(\"expecting valid const value\")"
+      << endl;
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  } else if (ttype->is_struct() || ttype->is_xception()) {
+    render_const_struct(ttype, tvalue);
+  } else if (ttype->is_container()) {
+    f_gen_ << indent() << "{" << endl;
+    indent_up();
+
+    if (ttype->is_list()) {
+      render_const_list(ttype, tvalue);
+    } else if (ttype->is_set()) {
+      render_const_set(ttype, tvalue);
+    } else if (ttype->is_map()) {
+      render_const_map(ttype, tvalue);
+    } else {
+      throw "cannot generate const container value for " + ttype->get_name();
+    }
+
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  } else {
+    throw "cannot generate const value for " + ttype->get_name();
+  }
+}
+
+void t_rs_generator::render_const_struct(t_type* ttype, t_const_value*) {
+  if (((t_struct*)ttype)->is_union()) {
+    f_gen_ << indent() << "{" << endl;
+    indent_up();
+    f_gen_ << indent() << "unimplemented!()" << endl;
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  } else {
+    f_gen_ << indent() << "{" << endl;
+    indent_up();
+    f_gen_ << indent() << "unimplemented!()" << endl;
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  }
+}
+
+void t_rs_generator::render_const_list(t_type* ttype, t_const_value* tvalue) {
+  t_type* elem_type = ((t_list*)ttype)->get_elem_type();
+  f_gen_ << indent() << "let mut l: Vec<" << to_rust_type(elem_type) << "> = Vec::new();" << endl;
+  const vector<t_const_value*>& elems = tvalue->get_list();
+  vector<t_const_value*>::const_iterator elem_iter;
+  for(elem_iter = elems.begin(); elem_iter != elems.end(); ++elem_iter) {
+    t_const_value* elem_value = (*elem_iter);
+    render_container_const_value("l.push", elem_type, elem_value);
+  }
+  f_gen_ << indent() << "l" << endl;
+}
+
+void t_rs_generator::render_const_set(t_type* ttype, t_const_value* tvalue) {
+  t_type* elem_type = ((t_set*)ttype)->get_elem_type();
+  f_gen_ << indent() << "let mut s: BTreeSet<" << to_rust_type(elem_type) << "> = BTreeSet::new();" << endl;
+  const vector<t_const_value*>& elems = tvalue->get_list();
+  vector<t_const_value*>::const_iterator elem_iter;
+  for(elem_iter = elems.begin(); elem_iter != elems.end(); ++elem_iter) {
+    t_const_value* elem_value = (*elem_iter);
+    render_container_const_value("s.insert", elem_type, elem_value);
+  }
+  f_gen_ << indent() << "s" << endl;
+}
+
+void t_rs_generator::render_const_map(t_type* ttype, t_const_value* tvalue) {
+  t_type* key_type = ((t_map*)ttype)->get_key_type();
+  t_type* val_type = ((t_map*)ttype)->get_val_type();
+  f_gen_
+    << indent()
+    << "let mut m: BTreeMap<"
+    << to_rust_type(key_type) << ", " << to_rust_type(val_type)
+    << "> = BTreeMap::new();"
+    << endl;
+  const map<t_const_value*, t_const_value*>& elems = tvalue->get_map();
+  map<t_const_value*, t_const_value*>::const_iterator elem_iter;
+  for (elem_iter = elems.begin(); elem_iter != elems.end(); ++elem_iter) {
+    t_const_value* key_value = elem_iter->first;
+    t_const_value* val_value = elem_iter->second;
+    if (get_true_type(key_type)->is_base_type()) {
+      f_gen_ << indent() << "let k = ";
+      render_const_value(key_type, key_value);
+      f_gen_ << ";" << endl;
+    } else {
+      f_gen_ << indent() << "let k = {" << endl;
+      indent_up();
+      render_const_value(key_type, key_value);
+      indent_down();
+      f_gen_ << indent() << "};" << endl;
+    }
+    if (get_true_type(val_type)->is_base_type()) {
+      f_gen_ << indent() << "let v = ";
+      render_const_value(val_type, val_value);
+      f_gen_ << ";" << endl;
+    } else {
+      f_gen_ << indent() << "let v = {" << endl;
+      indent_up();
+      render_const_value(val_type, val_value);
+      indent_down();
+      f_gen_ << indent() << "};" << endl;
+    }
+    f_gen_ <<  indent() << "m.insert(k, v);" << endl;
+  }
+  f_gen_ << indent() << "m" << endl;
+}
+
+void t_rs_generator::render_container_const_value(
+  const string& insert_function,
+  t_type* ttype,
+  t_const_value* tvalue
+) {
+  if (get_true_type(ttype)->is_base_type()) {
+    f_gen_ << indent() << insert_function << "(";
+    render_const_value(ttype, tvalue);
+    f_gen_ << ");" << endl;
+  } else {
+    f_gen_ << indent() << insert_function << "(" << endl;
+    indent_up();
+    render_const_value(ttype, tvalue);
+    indent_down();
+    f_gen_ << indent() << ");" << endl;
+  }
+}
+
+//-----------------------------------------------------------------------------
+//
+// Typedefs
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::generate_typedef(t_typedef* ttypedef) {
+  std::string actual_type = to_rust_type(ttypedef->get_type());
+  f_gen_ << "pub type " << rust_safe_name(ttypedef->get_symbolic()) << " = " << actual_type << ";" << endl;
+  f_gen_ << endl;
+}
+
+//-----------------------------------------------------------------------------
+//
+// Enums
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::generate_enum(t_enum* tenum) {
+  string enum_name(rust_camel_case(tenum->get_name()));
+  render_enum_definition(tenum, enum_name);
+  render_enum_impl(enum_name);
+  render_enum_conversion(tenum, enum_name);
+}
+
+void t_rs_generator::render_enum_definition(t_enum* tenum, const string& enum_name) {
+  render_rustdoc((t_doc*) tenum);
+  f_gen_ << "#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]" << endl;
+  f_gen_ << "pub enum " << enum_name << " {" << endl;
+  indent_up();
+
+  vector<t_enum_value*> constants = tenum->get_constants();
+  vector<t_enum_value*>::iterator constants_iter;
+  for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) {
+    t_enum_value* val = (*constants_iter);
+    render_rustdoc((t_doc*) val);
+    f_gen_
+      << indent()
+      << uppercase(val->get_name())
+      << " = "
+      << val->get_value()
+      << ","
+      << endl;
+  }
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_enum_impl(const string& enum_name) {
+  f_gen_ << "impl " << enum_name << " {" << endl;
+  indent_up();
+
+  f_gen_
+    << indent()
+    << "pub fn write_to_out_protocol(&self, o_prot: &mut TOutputProtocol) -> thrift::Result<()> {"
+    << endl;
+  indent_up();
+  f_gen_ << indent() << "o_prot.write_i32(*self as i32)" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  f_gen_
+    << indent()
+    << "pub fn read_from_in_protocol(i_prot: &mut TInputProtocol) -> thrift::Result<" << enum_name << "> {"
+    << endl;
+  indent_up();
+
+  f_gen_ << indent() << "let enum_value = i_prot.read_i32()?;" << endl;
+  f_gen_ << indent() << enum_name << "::try_from(enum_value)";
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_enum_conversion(t_enum* tenum, const string& enum_name) {
+  f_gen_ << "impl TryFrom<i32> for " << enum_name << " {" << endl;
+  indent_up();
+
+  f_gen_ << indent() << "type Err = thrift::Error;";
+
+  f_gen_ << indent() << "fn try_from(i: i32) -> Result<Self, Self::Err> {" << endl;
+  indent_up();
+
+  f_gen_ << indent() << "match i {" << endl;
+  indent_up();
+
+  vector<t_enum_value*> constants = tenum->get_constants();
+  vector<t_enum_value*>::iterator constants_iter;
+  for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) {
+    t_enum_value* val = (*constants_iter);
+    f_gen_
+      << indent()
+      << val->get_value()
+      << " => Ok(" << enum_name << "::" << uppercase(val->get_name()) << "),"
+      << endl;
+  }
+  f_gen_ << indent() << "_ => {" << endl;
+  indent_up();
+  render_rift_error(
+    "Protocol",
+    "ProtocolError",
+    "ProtocolErrorKind::InvalidData",
+    "format!(\"cannot convert enum constant {} to " + enum_name + "\", i)"
+  );
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+//-----------------------------------------------------------------------------
+//
+// Structs, Unions and Exceptions
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::generate_xception(t_struct* txception) {
+  render_struct(rust_struct_name(txception), txception, t_rs_generator::T_EXCEPTION);
+}
+
+void t_rs_generator::generate_struct(t_struct* tstruct) {
+  if (tstruct->is_union()) {
+    render_union(tstruct);
+  } else if (tstruct->is_struct()) {
+    render_struct(rust_struct_name(tstruct), tstruct, t_rs_generator::T_REGULAR);
+  } else {
+    throw "cannot generate struct for exception";
+  }
+}
+
+void t_rs_generator::render_struct(
+  const string& struct_name,
+  t_struct* tstruct,
+  t_rs_generator::e_struct_type struct_type
+) {
+  render_type_comment(struct_name);
+  render_struct_definition(struct_name, tstruct, struct_type);
+  render_struct_impl(struct_name, tstruct, struct_type);
+  if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) {
+    render_struct_default_trait_impl(struct_name, tstruct);
+  }
+  if (struct_type == t_rs_generator::T_EXCEPTION) {
+    render_exception_struct_error_trait_impls(struct_name, tstruct);
+  }
+}
+
+void t_rs_generator::render_struct_definition(
+  const string& struct_name,
+  t_struct* tstruct,
+  t_rs_generator::e_struct_type struct_type
+) {
+  render_rustdoc((t_doc*) tstruct);
+  f_gen_ << "#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]" << endl;
+  f_gen_ << visibility_qualifier(struct_type) << "struct " << struct_name << " {" << endl;
+
+  // render the members
+  vector<t_field*> members = tstruct->get_sorted_members();
+  if (!members.empty()) {
+    indent_up();
+
+    vector<t_field*>::iterator members_iter;
+    for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field* member = (*members_iter);
+      t_field::e_req member_req = actual_field_req(member, struct_type);
+
+      string rust_type = to_rust_type(member->get_type());
+      rust_type = is_optional(member_req) ? "Option<" + rust_type + ">" : rust_type;
+
+      render_rustdoc((t_doc*) member);
+      f_gen_
+        << indent()
+        << visibility_qualifier(struct_type)
+        << rust_field_name(member) << ": " << rust_type << ","
+        << endl;
+    }
+
+    indent_down();
+  }
+
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_exception_struct_error_trait_impls(const string& struct_name, t_struct* tstruct) {
+  // error::Error trait
+  f_gen_ << "impl Error for " << struct_name << " {" << endl;
+  indent_up();
+  f_gen_ << indent() << "fn description(&self) -> &str {" << endl;
+  indent_up();
+  f_gen_ << indent() << "\"" << "remote service threw " << tstruct->get_name() << "\"" << endl; // use *original* name
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+
+  // convert::From trait
+  f_gen_ << "impl From<" << struct_name << "> for thrift::Error {" << endl;
+  indent_up();
+  f_gen_ << indent() << "fn from(e: " << struct_name << ") -> Self {" << endl;
+  indent_up();
+  f_gen_ << indent() << "thrift::Error::User(Box::new(e))" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+
+  // fmt::Display trait
+  f_gen_ << "impl Display for " << struct_name << " {" << endl;
+  indent_up();
+  f_gen_ << indent() << "fn fmt(&self, f: &mut Formatter) -> fmt::Result {" << endl;
+  indent_up();
+  f_gen_ << indent() << "self.description().fmt(f)" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_struct_default_trait_impl(const string& struct_name, t_struct* tstruct) {
+  bool has_required_field = false;
+
+  const vector<t_field*>& members = tstruct->get_sorted_members();
+  vector<t_field*>::const_iterator members_iter;
+  for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = *members_iter;
+    if (!is_optional(member->get_req())) {
+      has_required_field = true;
+      break;
+    }
+  }
+
+  if (has_required_field) {
+    return;
+  }
+
+  f_gen_ << "impl Default for " << struct_name << " {" << endl;
+  indent_up();
+  f_gen_ << indent() << "fn default() -> Self {" << endl;
+  indent_up();
+
+  if (members.empty()) {
+    f_gen_ << indent() << struct_name << "{}" << endl;
+  } else {
+    f_gen_ << indent() << struct_name << "{" << endl;
+    indent_up();
+    for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field *member = (*members_iter);
+      string member_name(rust_field_name(member));
+      f_gen_ << indent() << member_name << ": " << opt_in_req_out_value(member->get_type()) << "," << endl;
+    }
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  }
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_struct_impl(
+  const string& struct_name,
+  t_struct* tstruct,
+  t_rs_generator::e_struct_type struct_type
+) {
+  f_gen_ << "impl " << struct_name << " {" << endl;
+  indent_up();
+
+  if (struct_type == t_rs_generator::T_REGULAR || struct_type == t_rs_generator::T_EXCEPTION) {
+    render_struct_constructor(struct_name, tstruct, struct_type);
+  }
+
+  render_struct_sync_read(struct_name, tstruct, struct_type);
+  render_struct_sync_write(tstruct, struct_type);
+
+  if (struct_type == t_rs_generator::T_RESULT) {
+    render_result_struct_to_result_method(tstruct);
+  }
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_struct_constructor(
+  const string& struct_name,
+  t_struct* tstruct,
+  t_rs_generator::e_struct_type struct_type
+) {
+  const vector<t_field*>& members = tstruct->get_sorted_members();
+  vector<t_field*>::const_iterator members_iter;
+
+  // build the convenience type parameters that allows us to pass unwrapped values to a constructor and
+  // have them automatically converted into Option<value>
+  bool first_arg = true;
+
+  ostringstream generic_type_parameters;
+  ostringstream generic_type_qualifiers;
+  for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = (*members_iter);
+    t_field::e_req member_req = actual_field_req(member, struct_type);
+
+    if (is_optional(member_req)) {
+      if (first_arg) {
+        first_arg = false;
+      } else {
+        generic_type_parameters << ", ";
+        generic_type_qualifiers << ", ";
+      }
+      generic_type_parameters << "F" << member->get_key();
+      generic_type_qualifiers << "F" << member->get_key() << ": Into<Option<" << to_rust_type(member->get_type()) << ">>";
+    }
+  }
+
+  string type_parameter_string = generic_type_parameters.str();
+  if (type_parameter_string.length() != 0) {
+    type_parameter_string = "<" + type_parameter_string + ">";
+  }
+
+  string type_qualifier_string = generic_type_qualifiers.str();
+  if (type_qualifier_string.length() != 0) {
+    type_qualifier_string = "where " + type_qualifier_string + " ";
+  }
+
+  // now build the actual constructor arg list
+  // when we're building this list we have to use the type parameters in place of the actual type names
+  // if necessary
+  ostringstream args;
+  first_arg = true;
+  for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = (*members_iter);
+    t_field::e_req member_req = actual_field_req(member, struct_type);
+    string member_name(rust_field_name(member));
+
+    if (first_arg) {
+      first_arg = false;
+    } else {
+      args << ", ";
+    }
+
+    if (is_optional(member_req)) {
+      args << member_name << ": " << "F" << member->get_key();
+    } else {
+      args << member_name << ": " << to_rust_type(member->get_type());
+    }
+  }
+
+  string arg_string = args.str();
+
+  string visibility(visibility_qualifier(struct_type));
+  f_gen_
+    << indent()
+    << visibility
+    << "fn new"
+    << type_parameter_string
+    << "("
+    << arg_string
+    << ") -> "
+    << struct_name
+    << " "
+    << type_qualifier_string
+    << "{"
+    << endl;
+  indent_up();
+
+  if (members.size() == 0) {
+    f_gen_ << indent() << struct_name << " {}" << endl;
+  } else {
+    f_gen_ << indent() << struct_name << " {" << endl;
+    indent_up();
+
+    for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field* member = (*members_iter);
+      t_field::e_req member_req = actual_field_req(member, struct_type);
+      string member_name(rust_field_name(member));
+
+      if (is_optional(member_req)) {
+        f_gen_ << indent() << member_name << ": " << member_name << ".into()," << endl;
+      } else {
+        f_gen_ << indent() << member_name << ": " << member_name << "," << endl;
+      }
+    }
+
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  }
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_result_struct_to_result_method(t_struct* tstruct) {
+  // we don't use the rust struct name in this method, just the service call name
+  string service_call_name = tstruct->get_name();
+
+  // check that we actually have a result
+  size_t index = service_call_name.find(RESULT_STRUCT_SUFFIX, 0);
+  if (index == std::string::npos) {
+    throw "result struct " + service_call_name + " missing result suffix";
+  } else {
+     service_call_name.replace(index, 6, "");
+  }
+
+  const vector<t_field*>& members = tstruct->get_sorted_members();
+  vector<t_field*>::const_iterator members_iter;
+
+  // find out what the call's expected return type was
+  string rust_return_type = "()";
+  for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = (*members_iter);
+    if (member->get_name() == SERVICE_RESULT_VARIABLE) { // don't have to check safe name here
+      rust_return_type = to_rust_type(member->get_type());
+      break;
+    }
+  }
+
+  // NOTE: ideally I would generate the branches and render them separately
+  // I tried this however, and the resulting code was harder to understand
+  // maintaining a rendered branch count (while a little ugly) got me the
+  // rendering I wanted with code that was reasonably understandable
+
+  f_gen_ << indent() << "fn ok_or(self) -> thrift::Result<" << rust_return_type << "> {" << endl;
+  indent_up();
+
+  int rendered_branch_count = 0;
+
+  // render the exception branches
+  for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* tfield = (*members_iter);
+    if (tfield->get_name() != SERVICE_RESULT_VARIABLE) { // don't have to check safe name here
+      string field_name("self." + rust_field_name(tfield));
+      string branch_statement = rendered_branch_count == 0 ? "if" : "} else if";
+
+      f_gen_ << indent() << branch_statement << " " << field_name << ".is_some() {" << endl;
+      indent_up();
+      f_gen_ << indent() << "Err(thrift::Error::User(Box::new(" << field_name << ".unwrap())))" << endl;
+      indent_down();
+
+      rendered_branch_count++;
+    }
+  }
+
+  // render the return value branches
+  if (rust_return_type == "()") {
+    if (rendered_branch_count == 0) {
+      // we have the unit return and this service call has no user-defined
+      // exceptions. this means that we've a trivial return (happens with oneways)
+      f_gen_ << indent() << "Ok(())" << endl;
+    } else {
+      // we have the unit return, but there are user-defined exceptions
+      // if we've gotten this far then we have the default return (i.e. call successful)
+      f_gen_ << indent() << "} else {" << endl;
+      indent_up();
+      f_gen_ << indent() << "Ok(())" << endl;
+      indent_down();
+      f_gen_ << indent() << "}" << endl;
+    }
+  } else {
+    string branch_statement = rendered_branch_count == 0 ? "if" : "} else if";
+    f_gen_ << indent() << branch_statement << " self." << SERVICE_RESULT_VARIABLE << ".is_some() {" << endl;
+    indent_up();
+    f_gen_ << indent() << "Ok(self." << SERVICE_RESULT_VARIABLE << ".unwrap())" << endl;
+    indent_down();
+    f_gen_ << indent() << "} else {" << endl;
+    indent_up();
+    // if we haven't found a valid return value *or* a user exception
+    // then we're in trouble; return a default error
+    render_rift_error(
+      "Application",
+      "ApplicationError",
+      "ApplicationErrorKind::MissingResult",
+      "\"no result received for " + service_call_name + "\""
+    );
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  }
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_union(t_struct* tstruct) {
+  string union_name(rust_struct_name(tstruct));
+  render_type_comment(union_name);
+  render_union_definition(union_name, tstruct);
+  render_union_impl(union_name, tstruct);
+}
+
+void t_rs_generator::render_union_definition(const string& union_name, t_struct* tstruct) {
+  const vector<t_field*>& members = tstruct->get_sorted_members();
+  if (members.empty()) {
+    throw "cannot generate rust enum with 0 members"; // may be valid thrift, but it's invalid rust
+  }
+
+  f_gen_ << "#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]" << endl;
+  f_gen_ << "pub enum " << union_name << " {" << endl;
+  indent_up();
+
+  vector<t_field*>::const_iterator member_iter;
+  for(member_iter = members.begin(); member_iter != members.end(); ++member_iter) {
+    t_field* tfield = (*member_iter);
+    f_gen_
+      << indent()
+      << rust_union_field_name(tfield)
+      << "(" << to_rust_type(tfield->get_type()) << "),"
+      << endl;
+  }
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_union_impl(const string& union_name, t_struct* tstruct) {
+  f_gen_ << "impl " << union_name << " {" << endl;
+  indent_up();
+
+  render_union_sync_read(union_name, tstruct);
+  render_union_sync_write(union_name, tstruct);
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+//-----------------------------------------------------------------------------
+//
+// Sync Struct Write
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::render_struct_sync_write(
+    t_struct *tstruct,
+    t_rs_generator::e_struct_type struct_type
+) {
+  f_gen_
+    << indent()
+    << visibility_qualifier(struct_type)
+    << "fn write_to_out_protocol(&self, o_prot: &mut TOutputProtocol) -> thrift::Result<()> {"
+    << endl;
+  indent_up();
+
+  // write struct header to output protocol
+  // note: use the *original* struct name here
+  f_gen_ << indent() << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << endl;
+  f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << endl;
+
+  // write struct members to output protocol
+  vector<t_field*> members = tstruct->get_sorted_members();
+  if (!members.empty()) {
+    vector<t_field*>::iterator members_iter;
+    for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field* member = (*members_iter);
+      t_field::e_req member_req = actual_field_req(member, struct_type);
+      string member_var("self." + rust_field_name(member));
+      render_struct_field_sync_write(member_var, false, member, member_req);
+    }
+  }
+
+  // write struct footer to output protocol
+  f_gen_ << indent() << "o_prot.write_field_stop()?;" << endl;
+  f_gen_ << indent() << "o_prot.write_struct_end()" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_union_sync_write(const string &union_name, t_struct *tstruct) {
+  f_gen_
+    << indent()
+    << "pub fn write_to_out_protocol(&self, o_prot: &mut TOutputProtocol) -> thrift::Result<()> {"
+    << endl;
+  indent_up();
+
+  // write struct header to output protocol
+  // note: use the *original* struct name here
+  f_gen_ << indent() << "let struct_ident = TStructIdentifier::new(\"" + tstruct->get_name() + "\");" << endl;
+  f_gen_ << indent() << "o_prot.write_struct_begin(&struct_ident)?;" << endl;
+
+  // write the enum field to the output protocol
+  vector<t_field*> members = tstruct->get_sorted_members();
+  if (!members.empty()) {
+    f_gen_ << indent() << "match *self {" << endl;
+    indent_up();
+    vector<t_field*>::iterator members_iter;
+    for(members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field* member = (*members_iter);
+      t_field::e_req member_req = t_field::T_REQUIRED;
+      t_type* ttype = member->get_type();
+      string match_var((ttype->is_base_type() && !ttype->is_string()) ? "f" : "ref f");
+      f_gen_
+        << indent()
+        << union_name << "::" << rust_union_field_name(member)
+        << "(" << match_var << ") => {"
+        << endl;
+      indent_up();
+      render_struct_field_sync_write("f", true, member, member_req);
+      indent_down();
+      f_gen_ << indent() << "}," << endl;
+    }
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  }
+
+  // write struct footer to output protocol
+  f_gen_ << indent() << "o_prot.write_field_stop()?;" << endl;
+  f_gen_ << indent() << "o_prot.write_struct_end()" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_struct_field_sync_write(
+  const string &field_var,
+  bool field_var_is_ref,
+  t_field *tfield,
+  t_field::e_req req
+) {
+  t_type* field_type = tfield->get_type();
+  t_type* actual_type = get_true_type(field_type);
+
+  ostringstream field_stream;
+  field_stream
+    << "TFieldIdentifier::new("
+    << "\"" << tfield->get_name() << "\"" << ", " // note: use *original* name
+    << to_rust_field_type_enum(field_type) << ", "
+    << tfield->get_key() << ")";
+  string field_ident_string = field_stream.str();
+
+  if (is_optional(req)) {
+    string let_var((actual_type->is_base_type() && !actual_type->is_string()) ? "fld_var" : "ref fld_var");
+    f_gen_ << indent() << "if let Some(" << let_var << ") = " << field_var << " {" << endl;
+    indent_up();
+    f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << endl;
+    render_type_sync_write("fld_var", true, field_type);
+    f_gen_ << indent() << "o_prot.write_field_end()?;" << endl;
+    f_gen_ << indent() << "()" << endl; // FIXME: remove this extraneous '()'
+    indent_down();
+    f_gen_ << indent() << "} else {" << endl; // FIXME: remove else branch
+    indent_up();
+    /* FIXME: rethink how I deal with OPT_IN_REQ_OUT
+    if (req == t_field::T_OPT_IN_REQ_OUT) {
+      f_gen_ << indent() << "let field_ident = " << field_ident_string << ";" << endl;
+      f_gen_ << indent() << "o_prot.write_field_begin(&field_ident)?;" << endl;
+      f_gen_ << indent() << "o_prot.write_field_end()?;" << endl;
+    }*/
+    f_gen_ << indent() << "()" << endl;
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  } else {
+    f_gen_ << indent() << "o_prot.write_field_begin(&" << field_ident_string << ")?;" << endl;
+    render_type_sync_write(field_var, field_var_is_ref, tfield->get_type());
+    f_gen_ << indent() << "o_prot.write_field_end()?;" << endl;
+  }
+}
+
+void t_rs_generator::render_type_sync_write(const string &type_var, bool type_var_is_ref, t_type *ttype) {
+  if (ttype->is_base_type()) {
+    t_base_type* tbase_type = (t_base_type*)ttype;
+    switch (tbase_type->get_base()) {
+    case t_base_type::TYPE_VOID:
+      throw "cannot write field of type TYPE_VOID to output protocol";
+    case t_base_type::TYPE_STRING: {
+      string ref(type_var_is_ref ? "" : "&");
+      if (tbase_type->is_binary()) {
+        f_gen_ << indent() << "o_prot.write_bytes(" + ref + type_var + ")?;" << endl;
+      } else {
+        f_gen_ << indent() << "o_prot.write_string(" + ref + type_var + ")?;" << endl;
+      }
+      return;
+    }
+    case t_base_type::TYPE_BOOL:
+      f_gen_ << indent() << "o_prot.write_bool(" + type_var + ")?;" << endl;
+      return;
+    case t_base_type::TYPE_I8:
+      f_gen_ << indent() << "o_prot.write_i8(" + type_var + ")?;" << endl;
+      return;
+    case t_base_type::TYPE_I16:
+      f_gen_ << indent() << "o_prot.write_i16(" + type_var + ")?;" << endl;
+      return;
+    case t_base_type::TYPE_I32:
+      f_gen_ << indent() << "o_prot.write_i32(" + type_var + ")?;" << endl;
+      return;
+    case t_base_type::TYPE_I64:
+      f_gen_ << indent() << "o_prot.write_i64(" + type_var + ")?;" << endl;
+      return;
+    case t_base_type::TYPE_DOUBLE:
+      f_gen_ << indent() << "o_prot.write_double(" + type_var + ".into())?;" << endl;
+      return;
+    }
+  } else if (ttype->is_typedef()) {
+    t_typedef* ttypedef = (t_typedef*) ttype;
+    render_type_sync_write(type_var, type_var_is_ref, ttypedef->get_type());
+    return;
+  } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) {
+    f_gen_ << indent() << type_var + ".write_to_out_protocol(o_prot)?;" << endl;
+    return;
+  } else if (ttype->is_map()) {
+    render_map_sync_write(type_var, type_var_is_ref, (t_map *) ttype);
+    return;
+  } else if (ttype->is_set()) {
+    render_set_sync_write(type_var, type_var_is_ref, (t_set *) ttype);
+    return;
+  } else if (ttype->is_list()) {
+    render_list_sync_write(type_var, type_var_is_ref, (t_list *) ttype);
+    return;
+  }
+
+  throw "cannot write unsupported type " + ttype->get_name();
+}
+
+void t_rs_generator::render_list_sync_write(const string &list_var, bool list_var_is_ref, t_list *tlist) {
+  t_type* elem_type = tlist->get_elem_type();
+
+  f_gen_
+    << indent()
+    << "o_prot.write_list_begin("
+    << "&TListIdentifier::new("
+    << to_rust_field_type_enum(elem_type) << ", "
+    << list_var << ".len() as i32" << ")"
+    << ")?;"
+    << endl;
+
+  string ref(list_var_is_ref ? "" : "&");
+  f_gen_ << indent() << "for e in " << ref << list_var << " {" << endl;
+  indent_up();
+  render_type_sync_write(needs_deref_on_container_write(elem_type) ? "*e" : "e", true, elem_type);
+  f_gen_ << indent() << "o_prot.write_list_end()?;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_set_sync_write(const string &set_var, bool set_var_is_ref, t_set *tset) {
+  t_type* elem_type = tset->get_elem_type();
+
+  f_gen_
+    << indent()
+    << "o_prot.write_set_begin("
+    << "&TSetIdentifier::new("
+    << to_rust_field_type_enum(elem_type) << ", "
+    << set_var << ".len() as i32" << ")"
+    << ")?;"
+    << endl;
+
+  string ref(set_var_is_ref ? "" : "&");
+  f_gen_ << indent() << "for e in " << ref << set_var << " {" << endl;
+  indent_up();
+  render_type_sync_write(needs_deref_on_container_write(elem_type) ? "*e" : "e", true, elem_type);
+  f_gen_ << indent() << "o_prot.write_set_end()?;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_map_sync_write(const string &map_var, bool map_var_is_ref, t_map *tmap) {
+  t_type* key_type = tmap->get_key_type();
+  t_type* val_type = tmap->get_val_type();
+
+  f_gen_
+    << indent()
+    << "o_prot.write_map_begin("
+    << "&TMapIdentifier::new("
+    << to_rust_field_type_enum(key_type) << ", "
+    << to_rust_field_type_enum(val_type) << ", "
+    << map_var << ".len() as i32)"
+    << ")?;"
+    << endl;
+
+  string ref(map_var_is_ref ? "" : "&");
+  f_gen_ << indent() << "for (k, v) in " << ref << map_var << " {" << endl;
+  indent_up();
+  render_type_sync_write(needs_deref_on_container_write(key_type) ? "*k" : "k", true, key_type);
+  render_type_sync_write(needs_deref_on_container_write(val_type) ? "*v" : "v", true, val_type);
+  f_gen_ << indent() << "o_prot.write_map_end()?;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+bool t_rs_generator::needs_deref_on_container_write(t_type* ttype) {
+  ttype = get_true_type(ttype);
+  return ttype->is_base_type() && !ttype->is_string();
+}
+
+//-----------------------------------------------------------------------------
+//
+// Sync Struct Read
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::render_struct_sync_read(
+    const string &struct_name,
+    t_struct *tstruct, t_rs_generator::e_struct_type struct_type
+) {
+  f_gen_
+    << indent()
+    << visibility_qualifier(struct_type)
+    << "fn read_from_in_protocol(i_prot: &mut TInputProtocol) -> thrift::Result<" << struct_name << "> {"
+    << endl;
+
+  indent_up();
+
+  f_gen_ << indent() << "i_prot.read_struct_begin()?;" << endl;
+
+  // create temporary variables: one for each field in the struct
+  const vector<t_field*> members = tstruct->get_sorted_members();
+  vector<t_field*>::const_iterator members_iter;
+  for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = (*members_iter);
+    t_field::e_req member_req = actual_field_req(member, struct_type);
+
+    f_gen_
+      << indent()
+      << "let mut " << struct_field_read_temp_variable(member)
+      << ": Option<" << to_rust_type(member->get_type()) << "> = ";
+      if (member_req == t_field::T_OPT_IN_REQ_OUT) {
+        f_gen_ << opt_in_req_out_value(member->get_type()) << ";";
+      } else {
+        f_gen_ << "None;";
+      }
+      f_gen_ << endl;
+  }
+
+  // now loop through the fields we've received
+  f_gen_ << indent() << "loop {" << endl; // start loop
+  indent_up();
+
+  // break out if you've found the Stop field
+  f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << endl;
+  f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << endl;
+  indent_up();
+  f_gen_ << indent() << "break;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  // now read all the fields found
+  f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl;
+  f_gen_ << indent() << "match field_id {" << endl; // start match
+  indent_up();
+
+  for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* tfield = (*members_iter);
+    f_gen_ << indent() << tfield->get_key() << " => {" << endl;
+    indent_up();
+    render_type_sync_read("val", tfield->get_type());
+    f_gen_ << indent() << struct_field_read_temp_variable(tfield) << " = Some(val);" << endl;
+    indent_down();
+    f_gen_ << indent() << "}," << endl;
+  }
+
+  // default case (skip fields)
+  f_gen_ << indent() << "_ => {" << endl;
+  indent_up();
+  f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  indent_down();
+  f_gen_ << indent() << "};" << endl; // finish match
+  f_gen_ << indent() << "i_prot.read_field_end()?;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl; // finish loop
+  f_gen_ << indent() << "i_prot.read_struct_end()?;" << endl; // read message footer from the wire
+
+  // verify that all required fields exist
+  for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* tfield = (*members_iter);
+    t_field::e_req req = actual_field_req(tfield, struct_type);
+    if (!is_optional(req)) {
+      f_gen_
+        << indent()
+        << "verify_required_field_exists("
+        << "\"" << struct_name << "." << rust_field_name(tfield) << "\""
+        << ", "
+        << "&" << struct_field_read_temp_variable(tfield)
+        << ")?;" << endl;
+    }
+  }
+
+  // construct the struct
+  if (members.size() == 0) {
+    f_gen_ << indent() << "let ret = " << struct_name << " {};" << endl;
+  } else {
+    f_gen_ << indent() << "let ret = " << struct_name << " {" << endl;
+    indent_up();
+
+    for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field* tfield = (*members_iter);
+      t_field::e_req req = actual_field_req(tfield, struct_type);
+      string field_name(rust_field_name(tfield));
+      string field_key = struct_field_read_temp_variable(tfield);
+      if (is_optional(req)) {
+        f_gen_ << indent() << field_name << ": " << field_key << "," << endl;
+      } else {
+        f_gen_
+          << indent()
+          << field_name
+          << ": "
+          << field_key
+          << ".expect(\"auto-generated code should have checked for presence of required fields\")"
+          << ","
+          << endl;
+      }
+    }
+
+    indent_down();
+    f_gen_ << indent() << "};" << endl;
+  }
+
+  // return the constructed value
+  f_gen_ << indent() << "Ok(ret)" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_union_sync_read(const string &union_name, t_struct *tstruct) {
+  f_gen_
+    << indent()
+    << "pub fn read_from_in_protocol(i_prot: &mut TInputProtocol) -> thrift::Result<" << union_name << "> {"
+    << endl;
+  indent_up();
+
+  // create temporary variables to hold the
+  // completed union as well as a count of fields read
+  f_gen_ << indent() << "let mut ret: Option<" << union_name << "> = None;" << endl;
+  f_gen_ << indent() << "let mut received_field_count = 0;" << endl;
+
+  // read the struct preamble
+  f_gen_ << indent() << "i_prot.read_struct_begin()?;" << endl;
+
+  // now loop through the fields we've received
+  f_gen_ << indent() << "loop {" << endl; // start loop
+  indent_up();
+
+  // break out if you've found the Stop field
+  f_gen_ << indent() << "let field_ident = i_prot.read_field_begin()?;" << endl;
+  f_gen_ << indent() << "if field_ident.field_type == TType::Stop {" << endl;
+  indent_up();
+  f_gen_ << indent() << "break;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  // now read all the fields found
+  f_gen_ << indent() << "let field_id = field_id(&field_ident)?;" << endl;
+  f_gen_ << indent() << "match field_id {" << endl; // start match
+  indent_up();
+
+  const vector<t_field*> members = tstruct->get_sorted_members();
+  vector<t_field*>::const_iterator members_iter;
+  for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = (*members_iter);
+    f_gen_ << indent() << member->get_key() << " => {" << endl;
+    indent_up();
+    render_type_sync_read("val", member->get_type());
+    f_gen_ << indent() << "if ret.is_none() {" << endl;
+    indent_up();
+    f_gen_
+      << indent()
+      << "ret = Some(" << union_name << "::" << rust_union_field_name(member) << "(val));"
+      << endl;
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+    f_gen_ << indent() << "received_field_count += 1;" << endl;
+    indent_down();
+    f_gen_ << indent() << "}," << endl;
+  }
+
+  // default case (skip fields)
+  f_gen_ << indent() << "_ => {" << endl;
+  indent_up();
+  f_gen_ << indent() << "i_prot.skip(field_ident.field_type)?;" << endl;
+  f_gen_ << indent() << "received_field_count += 1;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  indent_down();
+  f_gen_ << indent() << "};" << endl; // finish match
+  f_gen_ << indent() << "i_prot.read_field_end()?;" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl; // finish loop
+  f_gen_ << indent() << "i_prot.read_struct_end()?;" << endl; // finish reading message from wire
+
+  // return the value or an error
+  f_gen_ << indent() << "if received_field_count == 0 {" << endl;
+  indent_up();
+  render_rift_error(
+    "Protocol",
+    "ProtocolError",
+    "ProtocolErrorKind::InvalidData",
+    "\"received empty union from remote " + union_name + "\""
+  );
+  indent_down();
+  f_gen_ << indent() << "} else if received_field_count > 1 {" << endl;
+  indent_up();
+  render_rift_error(
+    "Protocol",
+    "ProtocolError",
+    "ProtocolErrorKind::InvalidData",
+    "\"received multiple fields for union from remote " + union_name + "\""
+  );
+  indent_down();
+  f_gen_ << indent() << "} else {" << endl;
+  indent_up();
+  f_gen_ << indent() << "Ok(ret.expect(\"return value should have been constructed\"))" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+// Construct the rust representation of all supported types from the wire.
+void t_rs_generator::render_type_sync_read(const string &type_var, t_type *ttype) {
+  if (ttype->is_base_type()) {
+    t_base_type* tbase_type = (t_base_type*)ttype;
+    switch (tbase_type->get_base()) {
+    case t_base_type::TYPE_VOID:
+      throw "cannot read field of type TYPE_VOID from input protocol";
+    case t_base_type::TYPE_STRING:
+      if (tbase_type->is_binary()) {
+        f_gen_ << indent() << "let " << type_var << " = i_prot.read_bytes()?;" << endl;
+      } else {
+        f_gen_ << indent() << "let " << type_var << " = i_prot.read_string()?;" << endl;
+      }
+      return;
+    case t_base_type::TYPE_BOOL:
+      f_gen_ << indent() << "let " << type_var << " = i_prot.read_bool()?;" << endl;
+      return;
+    case t_base_type::TYPE_I8:
+      f_gen_ << indent() << "let " << type_var << " = i_prot.read_i8()?;" << endl;
+      return;
+    case t_base_type::TYPE_I16:
+      f_gen_ << indent() << "let " << type_var << " = i_prot.read_i16()?;" << endl;
+      return;
+    case t_base_type::TYPE_I32:
+      f_gen_ << indent() << "let " << type_var << " = i_prot.read_i32()?;" << endl;
+      return;
+    case t_base_type::TYPE_I64:
+      f_gen_ << indent() << "let " << type_var << " = i_prot.read_i64()?;" << endl;
+      return;
+    case t_base_type::TYPE_DOUBLE:
+      f_gen_ << indent() << "let " << type_var << " = OrderedFloat::from(i_prot.read_double()?);" << endl;
+      return;
+    }
+  } else if (ttype->is_typedef()) {
+    t_typedef* ttypedef = (t_typedef*)ttype;
+    render_type_sync_read(type_var, ttypedef->get_type());
+    return;
+  } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) {
+    f_gen_
+      << indent()
+      << "let " << type_var << " = " <<  to_rust_type(ttype) << "::read_from_in_protocol(i_prot)?;"
+      << endl;
+    return;
+  } else if (ttype->is_map()) {
+    render_map_sync_read((t_map *) ttype, type_var);
+    return;
+  } else if (ttype->is_set()) {
+    render_set_sync_read((t_set *) ttype, type_var);
+    return;
+  } else if (ttype->is_list()) {
+    render_list_sync_read((t_list *) ttype, type_var);
+    return;
+  }
+
+  throw "cannot read unsupported type " + ttype->get_name();
+}
+
+// Construct the rust representation of a list from the wire.
+void t_rs_generator::render_list_sync_read(t_list *tlist, const string &list_var) {
+  t_type* elem_type = tlist->get_elem_type();
+
+  f_gen_ << indent() << "let list_ident = i_prot.read_list_begin()?;" << endl;
+  f_gen_
+    << indent()
+    << "let mut " << list_var << ": " << to_rust_type((t_type*) tlist)
+    << " = Vec::with_capacity(list_ident.size as usize);"
+    << endl;
+  f_gen_ << indent() << "for _ in 0..list_ident.size {" << endl;
+
+  indent_up();
+
+  string list_elem_var = tmp("list_elem_");
+  render_type_sync_read(list_elem_var, elem_type);
+  f_gen_ << indent() << list_var << ".push(" << list_elem_var << ");" << endl;
+
+  indent_down();
+
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << indent() << "i_prot.read_list_end()?;" << endl;
+}
+
+// Construct the rust representation of a set from the wire.
+void t_rs_generator::render_set_sync_read(t_set *tset, const string &set_var) {
+  t_type* elem_type = tset->get_elem_type();
+
+  f_gen_ << indent() << "let set_ident = i_prot.read_set_begin()?;" << endl;
+  f_gen_
+    << indent()
+    << "let mut " << set_var << ": " << to_rust_type((t_type*) tset)
+    << " = BTreeSet::new();"
+    << endl;
+  f_gen_ << indent() << "for _ in 0..set_ident.size {" << endl;
+
+  indent_up();
+
+  string set_elem_var = tmp("set_elem_");
+  render_type_sync_read(set_elem_var, elem_type);
+  f_gen_ << indent() << set_var << ".insert(" << set_elem_var << ");" << endl;
+
+  indent_down();
+
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << indent() << "i_prot.read_set_end()?;" << endl;
+}
+
+// Construct the rust representation of a map from the wire.
+void t_rs_generator::render_map_sync_read(t_map *tmap, const string &map_var) {
+  t_type* key_type = tmap->get_key_type();
+  t_type* val_type = tmap->get_val_type();
+
+  f_gen_ << indent() << "let map_ident = i_prot.read_map_begin()?;" << endl;
+  f_gen_
+    << indent()
+    << "let mut " << map_var << ": " << to_rust_type((t_type*) tmap)
+    << " = BTreeMap::new();"
+    << endl;
+  f_gen_ << indent() << "for _ in 0..map_ident.size {" << endl;
+
+  indent_up();
+
+  string key_elem_var = tmp("map_key_");
+  render_type_sync_read(key_elem_var, key_type);
+  string val_elem_var = tmp("map_val_");
+  render_type_sync_read(val_elem_var, val_type);
+  f_gen_ << indent() << map_var << ".insert(" << key_elem_var << ", " << val_elem_var << ");" << endl;
+
+  indent_down();
+
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << indent() << "i_prot.read_map_end()?;" << endl;
+}
+
+string t_rs_generator::struct_field_read_temp_variable(t_field* tfield) {
+  std::ostringstream foss;
+  foss << "f_" << tfield->get_key();
+  return foss.str();
+}
+
+//-----------------------------------------------------------------------------
+//
+// Sync Client
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::generate_service(t_service* tservice) {
+  render_sync_client(tservice);
+  render_sync_processor(tservice);
+  render_service_call_structs(tservice);
+}
+
+void t_rs_generator::render_service_call_structs(t_service* tservice) {
+  const std::vector<t_function*> functions = tservice->get_functions();
+  std::vector<t_function*>::const_iterator func_iter;
+
+  // thrift args for service calls are packed
+  // into a struct that's transmitted over the wire, so
+  // generate structs for those too
+  //
+  // thrift returns are *also* packed into a struct
+  // that's passed over the wire, so, generate the struct
+  // for that too. Note that this result struct *also*
+  // contains the exceptions as well
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* tfunc = (*func_iter);
+    render_struct(rust_struct_name(tfunc->get_arglist()), tfunc->get_arglist(), t_rs_generator::T_ARGS);
+    if (!tfunc->is_oneway()) {
+      render_result_value_struct(tfunc);
+    }
+  }
+}
+
+void t_rs_generator::render_sync_client(t_service* tservice) {
+  string client_impl_name(rust_sync_client_impl_name(tservice));
+
+  render_type_comment(tservice->get_name() + " service client"); // note: use *original* name
+  render_sync_client_trait(tservice);
+  render_sync_client_marker_trait(tservice);
+  render_sync_client_definition_and_impl(client_impl_name);
+  render_sync_client_tthriftclient_impl(client_impl_name);
+  render_sync_client_marker_trait_impls(tservice, client_impl_name); f_gen_ << endl;
+  render_sync_client_process_impl(tservice);
+}
+
+void t_rs_generator::render_sync_client_trait(t_service *tservice) {
+  string extension = "";
+  if (tservice->get_extends()) {
+    t_service* extends = tservice->get_extends();
+    extension = " : " + rust_namespace(extends) + rust_sync_client_trait_name(extends);
+  }
+
+  render_rustdoc((t_doc*) tservice);
+  f_gen_ << "pub trait " << rust_sync_client_trait_name(tservice) << extension << " {" << endl;
+  indent_up();
+
+  const std::vector<t_function*> functions = tservice->get_functions();
+  std::vector<t_function*>::const_iterator func_iter;
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* tfunc = (*func_iter);
+    string func_name = service_call_client_function_name(tfunc);
+    string func_args = rust_sync_service_call_declaration(tfunc);
+    string func_return = to_rust_type(tfunc->get_returntype());
+    render_rustdoc((t_doc*) tfunc);
+    f_gen_ << indent() << "fn " << func_name <<  func_args << " -> thrift::Result<" << func_return << ">;" << endl;
+  }
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_sync_client_marker_trait(t_service *tservice) {
+  f_gen_ << indent() << "pub trait " << rust_sync_client_marker_trait_name(tservice) << " {}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_sync_client_marker_trait_impls(t_service *tservice, const string &impl_struct_name) {
+  f_gen_
+    << indent()
+    << "impl " << rust_namespace(tservice) << rust_sync_client_marker_trait_name(tservice)
+    << " for " << impl_struct_name
+    << " {}"
+    << endl;
+
+  t_service* extends = tservice->get_extends();
+  if (extends) {
+    render_sync_client_marker_trait_impls(extends, impl_struct_name);
+  }
+}
+
+void t_rs_generator::render_sync_client_definition_and_impl(const string& client_impl_name) {
+  // render the definition for the client struct
+  f_gen_ << "pub struct " << client_impl_name << " {" << endl;
+  indent_up();
+  f_gen_ << indent() << "_i_prot: Box<TInputProtocol>," << endl;
+  f_gen_ << indent() << "_o_prot: Box<TOutputProtocol>," << endl;
+  f_gen_ << indent() << "_sequence_number: i32," << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+
+  // render the struct implementation
+  // this includes the new() function as well as the helper send/recv methods for each service call
+  f_gen_ << "impl " << client_impl_name << " {" << endl;
+  indent_up();
+  render_sync_client_lifecycle_functions(client_impl_name);
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_sync_client_lifecycle_functions(const string& client_struct) {
+  f_gen_
+    << indent()
+    << "pub fn new(input_protocol: Box<TInputProtocol>, output_protocol: Box<TOutputProtocol>) -> "
+    << client_struct
+    << " {"
+    << endl;
+  indent_up();
+
+  f_gen_
+    << indent()
+    << client_struct
+    << " { _i_prot: input_protocol, _o_prot: output_protocol, _sequence_number: 0 }"
+    << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_sync_client_tthriftclient_impl(const string &client_impl_name) {
+  f_gen_ << indent() << "impl TThriftClient for " << client_impl_name << " {" << endl;
+  indent_up();
+
+  f_gen_ << indent() << "fn i_prot_mut(&mut self) -> &mut TInputProtocol { &mut *self._i_prot }" << endl;
+  f_gen_ << indent() << "fn o_prot_mut(&mut self) -> &mut TOutputProtocol { &mut *self._o_prot }" << endl;
+  f_gen_ << indent() << "fn sequence_number(&self) -> i32 { self._sequence_number }" << endl;
+  f_gen_
+    << indent()
+    << "fn increment_sequence_number(&mut self) -> i32 { self._sequence_number += 1; self._sequence_number }"
+    << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_sync_client_process_impl(t_service* tservice) {
+  string marker_extension = "" + sync_client_marker_traits_for_extension(tservice);
+
+  f_gen_
+    << "impl <C: TThriftClient + " << rust_sync_client_marker_trait_name(tservice) << marker_extension << "> "
+    << rust_sync_client_trait_name(tservice)
+    << " for C {" << endl;
+  indent_up();
+
+  const std::vector<t_function*> functions = tservice->get_functions();
+  std::vector<t_function*>::const_iterator func_iter;
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* func = (*func_iter);
+    render_sync_send_recv_wrapper(func);
+  }
+
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+}
+
+string t_rs_generator::sync_client_marker_traits_for_extension(t_service *tservice) {
+  string marker_extension;
+
+  t_service* extends = tservice->get_extends();
+  if (extends) {
+    marker_extension = " + " + rust_namespace(extends) + rust_sync_client_marker_trait_name(extends);
+    marker_extension = marker_extension + sync_client_marker_traits_for_extension(extends);
+  }
+
+  return marker_extension;
+}
+
+void t_rs_generator::render_sync_send_recv_wrapper(t_function* tfunc) {
+  string func_name = service_call_client_function_name(tfunc);
+  string func_decl_args = rust_sync_service_call_declaration(tfunc);
+  string func_call_args = rust_sync_service_call_invocation(tfunc);
+  string func_return = to_rust_type(tfunc->get_returntype());
+
+  f_gen_
+    << indent()
+    << "fn " << func_name <<  func_decl_args << " -> thrift::Result<" << func_return
+    << "> {"
+    << endl;
+  indent_up();
+
+  f_gen_ << indent() << "(" << endl;
+  indent_up();
+  render_sync_send(tfunc);
+  indent_down();
+  f_gen_ << indent() << ")?;" << endl;
+  if (tfunc->is_oneway()) {
+    f_gen_ << indent() << "Ok(())" << endl;
+  } else {
+    render_sync_recv(tfunc);
+  }
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_sync_send(t_function* tfunc) {
+  f_gen_ << indent() << "{" << endl;
+  indent_up();
+
+  // increment the sequence number and generate the call header
+  string message_type = tfunc->is_oneway() ? "TMessageType::OneWay" : "TMessageType::Call";
+  f_gen_ << indent() << "self.increment_sequence_number();" << endl;
+  f_gen_
+    << indent()
+    << "let message_ident = "
+    << "TMessageIdentifier::new(\"" << tfunc->get_name() << "\", " // note: use *original* name
+    << message_type << ", "
+    << "self.sequence_number());"
+    << endl;
+  // pack the arguments into the containing struct that we'll write out over the wire
+  // note that this struct is generated even if we have 0 args
+  ostringstream struct_definition;
+  vector<t_field*> members = tfunc->get_arglist()->get_sorted_members();
+  vector<t_field*>::iterator members_iter;
+  for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+    t_field* member = (*members_iter);
+    string member_name(rust_field_name(member));
+    struct_definition << member_name << ": " << member_name << ", ";
+  }
+  string struct_fields = struct_definition.str();
+  if (struct_fields.size() > 0) {
+    struct_fields = struct_fields.substr(0, struct_fields.size() - 2); // strip trailing comma
+  }
+  f_gen_
+    << indent()
+    << "let call_args = "
+    << rust_struct_name(tfunc->get_arglist())
+    << " { "
+    << struct_fields
+    << " };"
+    << endl;
+  // write everything over the wire
+  f_gen_ << indent() << "self.o_prot_mut().write_message_begin(&message_ident)?;" << endl;
+  f_gen_ << indent() << "call_args.write_to_out_protocol(self.o_prot_mut())?;" << endl; // written even if we have 0 args
+  f_gen_ << indent() << "self.o_prot_mut().write_message_end()?;" << endl;
+  f_gen_ << indent() << "self.o_prot_mut().flush()" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_sync_recv(t_function* tfunc) {
+  f_gen_ << indent() << "{" << endl;
+  indent_up();
+
+  f_gen_ << indent() << "let message_ident = self.i_prot_mut().read_message_begin()?;" << endl;
+  f_gen_ << indent() << "verify_expected_sequence_number(self.sequence_number(), message_ident.sequence_number)?;" << endl;
+  f_gen_ << indent() << "verify_expected_service_call(\"" << tfunc->get_name() <<"\", &message_ident.name)?;" << endl; // note: use *original* name
+  // FIXME: replace with a "try" block
+  f_gen_ << indent() << "if message_ident.message_type == TMessageType::Exception {" << endl;
+  indent_up();
+  f_gen_ << indent() << "let remote_error = thrift::Error::read_application_error_from_in_protocol(self.i_prot_mut())?;" << endl;
+  f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << endl;
+  f_gen_ << indent() << "return Err(thrift::Error::Application(remote_error))" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << indent() << "verify_expected_message_type(TMessageType::Reply, message_ident.message_type)?;" << endl;
+  f_gen_ << indent() << "let result = " << service_call_result_struct_name(tfunc) << "::read_from_in_protocol(self.i_prot_mut())?;" << endl;
+  f_gen_ << indent() << "self.i_prot_mut().read_message_end()?;" << endl;
+  f_gen_ << indent() << "result.ok_or()" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+string t_rs_generator::rust_sync_service_call_declaration(t_function* tfunc) {
+  ostringstream func_args;
+  func_args << "(&mut self";
+
+  if (has_args(tfunc)) {
+    func_args << ", "; // put comma after "&mut self"
+    func_args << struct_to_declaration(tfunc->get_arglist(), T_ARGS);
+  }
+
+  func_args << ")";
+  return func_args.str();
+}
+
+string t_rs_generator::rust_sync_service_call_invocation(t_function* tfunc, const string& field_prefix) {
+  ostringstream func_args;
+  func_args << "(";
+
+  if (has_args(tfunc)) {
+    func_args << struct_to_invocation(tfunc->get_arglist(), field_prefix);
+  }
+
+  func_args << ")";
+  return func_args.str();
+}
+
+string t_rs_generator::struct_to_declaration(t_struct* tstruct, t_rs_generator::e_struct_type struct_type) {
+  ostringstream args;
+
+  bool first_arg = true;
+  std::vector<t_field*> fields = tstruct->get_sorted_members();
+  std::vector<t_field*>::iterator field_iter;
+  for (field_iter = fields.begin(); field_iter != fields.end(); ++field_iter) {
+    t_field* tfield = (*field_iter);
+    t_field::e_req field_req = actual_field_req(tfield, struct_type);
+    string rust_type = to_rust_type(tfield->get_type());
+    rust_type = is_optional(field_req) ? "Option<" + rust_type + ">" : rust_type;
+
+    if (first_arg) {
+      first_arg = false;
+    } else {
+      args << ", ";
+    }
+
+    args << rust_field_name(tfield) << ": " << rust_type;
+  }
+
+  return args.str();
+}
+
+string t_rs_generator::struct_to_invocation(t_struct* tstruct, const string& field_prefix) {
+  ostringstream args;
+
+  bool first_arg = true;
+  std::vector<t_field*> fields = tstruct->get_sorted_members();
+  std::vector<t_field*>::iterator field_iter;
+  for (field_iter = fields.begin(); field_iter != fields.end(); ++field_iter) {
+    t_field* tfield = (*field_iter);
+
+    if (first_arg) {
+      first_arg = false;
+    } else {
+      args << ", ";
+    }
+
+    args << field_prefix << rust_field_name(tfield);
+  }
+
+  return args.str();
+}
+
+void t_rs_generator::render_result_value_struct(t_function* tfunc) {
+  string result_struct_name = service_call_result_struct_name(tfunc);
+  t_struct result(program_, result_struct_name);
+
+  t_field return_value(tfunc->get_returntype(), SERVICE_RESULT_VARIABLE, 0);
+  return_value.set_req(t_field::T_OPTIONAL);
+  if (!tfunc->get_returntype()->is_void()) {
+    result.append(&return_value);
+  }
+
+  t_struct* exceptions = tfunc->get_xceptions();
+  const vector<t_field*>& exception_types = exceptions->get_members();
+  vector<t_field*>::const_iterator exception_iter;
+  for(exception_iter = exception_types.begin(); exception_iter != exception_types.end(); ++exception_iter) {
+    t_field* exception_type = *exception_iter;
+    exception_type->set_req(t_field::T_OPTIONAL);
+    result.append(exception_type);
+  }
+
+  render_struct(result_struct_name, &result, t_rs_generator::T_RESULT);
+}
+
+//-----------------------------------------------------------------------------
+//
+// Sync Processor
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::render_sync_processor(t_service *tservice) {
+  render_type_comment(tservice->get_name() + " service processor"); // note: use *original* name
+  render_sync_handler_trait(tservice);
+  render_sync_processor_definition_and_impl(tservice);
+}
+
+void t_rs_generator::render_sync_handler_trait(t_service *tservice) {
+  string extension = "";
+  if (tservice->get_extends() != NULL) {
+    t_service* extends = tservice->get_extends();
+    extension = " : " + rust_namespace(extends) + rust_sync_handler_trait_name(extends);
+  }
+
+  const std::vector<t_function*> functions = tservice->get_functions();
+  std::vector<t_function*>::const_iterator func_iter;
+
+  render_rustdoc((t_doc*) tservice);
+  f_gen_ << "pub trait " << rust_sync_handler_trait_name(tservice) << extension << " {" << endl;
+  indent_up();
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* tfunc = (*func_iter);
+    string func_name = service_call_handler_function_name(tfunc);
+    string func_args = rust_sync_service_call_declaration(tfunc);
+    string func_return = to_rust_type(tfunc->get_returntype());
+    render_rustdoc((t_doc*) tfunc);
+    f_gen_
+      << indent()
+      << "fn "
+      << func_name <<  func_args
+      << " -> thrift::Result<" << func_return << ">;"
+      << endl;
+  }
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_sync_processor_definition_and_impl(t_service *tservice) {
+  string service_processor_name = rust_sync_processor_name(tservice);
+  string handler_trait_name = rust_sync_handler_trait_name(tservice);
+
+  // struct
+  f_gen_
+    << indent()
+    << "pub struct " << service_processor_name
+    << "<H: " << handler_trait_name
+    << "> {"
+    << endl;
+  indent_up();
+  f_gen_ << indent() << "handler: H," << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+
+  // delegating impl
+  f_gen_
+    << indent()
+    << "impl <H: " << handler_trait_name << "> "
+    << service_processor_name
+    << "<H> {"
+    << endl;
+  indent_up();
+  f_gen_ << indent() << "pub fn new(handler: H) -> " << service_processor_name << "<H> {" << endl;
+  indent_up();
+  f_gen_ << indent() << service_processor_name << " {" << endl;
+  indent_up();
+  f_gen_ << indent() << "handler: handler," << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  render_sync_process_delegation_functions(tservice);
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+
+  // actual impl
+  string service_actual_processor_name = rust_sync_processor_impl_name(tservice);
+  f_gen_ << indent() << "pub struct " << service_actual_processor_name << ";" << endl;
+  f_gen_ << endl;
+  f_gen_ << indent() << "impl " << service_actual_processor_name << " {" << endl;
+  indent_up();
+
+  vector<t_function*> functions = tservice->get_functions();
+  vector<t_function*>::iterator func_iter;
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* tfunc = (*func_iter);
+    render_sync_process_function(tfunc, handler_trait_name);
+  }
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+
+  // processor impl
+  f_gen_
+    << indent()
+    << "impl <H: "
+    << handler_trait_name << "> TProcessor for "
+    << service_processor_name
+    << "<H> {"
+    << endl;
+  indent_up();
+
+  f_gen_
+    << indent()
+    << "fn process(&mut self, i_prot: &mut TInputProtocol, o_prot: &mut TOutputProtocol) -> thrift::Result<()> {"
+    << endl;
+  indent_up();
+  f_gen_ << indent() << "let message_ident = i_prot.read_message_begin()?;" << endl;
+  f_gen_ << indent() << "match &*message_ident.name {" << endl; // [sigh] explicit deref coercion
+  indent_up();
+  render_process_match_statements(tservice);
+  f_gen_ << indent() << "method => {" << endl;
+  indent_up();
+  render_rift_error(
+    "Application",
+    "ApplicationError",
+    "ApplicationErrorKind::UnknownMethod",
+    "format!(\"unknown method {}\", method)"
+  );
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  f_gen_ << endl;
+}
+
+void t_rs_generator::render_sync_process_delegation_functions(t_service *tservice) {
+  string actual_processor(rust_namespace(tservice) + rust_sync_processor_impl_name(tservice));
+
+  vector<t_function*> functions = tservice->get_functions();
+  vector<t_function*>::iterator func_iter;
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* tfunc = (*func_iter);
+    string function_name("process_" + rust_snake_case(tfunc->get_name()));
+    f_gen_
+      << indent()
+      << "fn " << function_name
+      << "(&mut self, "
+      << "incoming_sequence_number: i32, "
+      << "i_prot: &mut TInputProtocol, "
+      << "o_prot: &mut TOutputProtocol) "
+      << "-> thrift::Result<()> {"
+      << endl;
+    indent_up();
+
+    f_gen_
+      << indent()
+      << actual_processor
+      << "::" << function_name
+      << "("
+      << "&mut self.handler, "
+      << "incoming_sequence_number, "
+      << "i_prot, "
+      << "o_prot"
+      << ")"
+      << endl;
+
+    indent_down();
+    f_gen_ << indent() << "}" << endl;
+  }
+
+  t_service* extends = tservice->get_extends();
+  if (extends) {
+    render_sync_process_delegation_functions(extends);
+  }
+}
+
+void t_rs_generator::render_process_match_statements(t_service* tservice) {
+  vector<t_function*> functions = tservice->get_functions();
+  vector<t_function*>::iterator func_iter;
+  for(func_iter = functions.begin(); func_iter != functions.end(); ++func_iter) {
+    t_function* tfunc = (*func_iter);
+    f_gen_ << indent() << "\"" << tfunc->get_name() << "\"" << " => {" << endl; // note: use *original* name
+    indent_up();
+    f_gen_
+      << indent()
+      << "self.process_" << rust_snake_case(tfunc->get_name())
+      << "(message_ident.sequence_number, i_prot, o_prot)"
+      << endl;
+    indent_down();
+    f_gen_ << indent() << "}," << endl;
+  }
+
+  t_service* extends = tservice->get_extends();
+  if (extends) {
+    render_process_match_statements(extends);
+  }
+}
+
+void t_rs_generator::render_sync_process_function(t_function *tfunc, const string &handler_type) {
+  string sequence_number_param("incoming_sequence_number");
+  string output_protocol_param("o_prot");
+
+  if (tfunc->is_oneway()) {
+    sequence_number_param = "_";
+    output_protocol_param = "_";
+  }
+
+  f_gen_
+    << indent()
+    << "pub fn process_" << rust_snake_case(tfunc->get_name())
+    << "<H: " << handler_type << ">"
+    << "(handler: &mut H, "
+    << sequence_number_param << ": i32, "
+    << "i_prot: &mut TInputProtocol, "
+    << output_protocol_param << ": &mut TOutputProtocol) "
+    << "-> thrift::Result<()> {"
+    << endl;
+
+  indent_up();
+
+  // *always* read arguments from the input protocol
+  f_gen_
+    << indent()
+    << "let "
+    << (has_non_void_args(tfunc) ? "args" : "_")
+    << " = "
+    << rust_struct_name(tfunc->get_arglist())
+    << "::read_from_in_protocol(i_prot)?;"
+    << endl;
+
+  f_gen_
+    << indent()
+    << "match handler."
+    << service_call_handler_function_name(tfunc)
+    << rust_sync_service_call_invocation(tfunc, "args.")
+    << " {"
+    << endl; // start match
+  indent_up();
+
+  // handler succeeded
+  string handler_return_variable = tfunc->is_oneway() || tfunc->get_returntype()->is_void() ? "_" : "handler_return";
+  f_gen_ << indent() << "Ok(" << handler_return_variable << ") => {" << endl;
+  indent_up();
+  render_sync_handler_succeeded(tfunc);
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+  // handler failed
+  f_gen_ << indent() << "Err(e) => {" << endl;
+  indent_up();
+  render_sync_handler_failed(tfunc);
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl; // end match
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl; // end function
+}
+
+void t_rs_generator::render_sync_handler_succeeded(t_function *tfunc) {
+  if (tfunc->is_oneway()) {
+    f_gen_ << indent() << "Ok(())" << endl;
+  } else {
+    f_gen_
+      << indent()
+      << "let message_ident = TMessageIdentifier::new("
+      << "\"" << tfunc->get_name() << "\", " // note: use *original* name
+      << "TMessageType::Reply, "
+      << "incoming_sequence_number);"
+      << endl;
+    f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl;
+    f_gen_ << indent() << "let ret = " << handler_successful_return_struct(tfunc) <<";" << endl;
+    f_gen_ << indent() << "ret.write_to_out_protocol(o_prot)?;" << endl;
+    f_gen_ << indent() << "o_prot.write_message_end()?;" << endl;
+    f_gen_ << indent() << "o_prot.flush()" << endl;
+  }
+}
+
+void t_rs_generator::render_sync_handler_failed(t_function *tfunc) {
+  string err_var("e");
+
+  f_gen_ << indent() << "match " << err_var << " {" << endl;
+  indent_up();
+
+  // if there are any user-defined exceptions for this service call handle them first
+  if (tfunc->get_xceptions() != NULL && tfunc->get_xceptions()->get_sorted_members().size() > 0) {
+    string user_err_var("usr_err");
+    f_gen_ << indent() << "thrift::Error::User(" << user_err_var << ") => {" << endl;
+    indent_up();
+    render_sync_handler_failed_user_exception_branch(tfunc);
+    indent_down();
+    f_gen_ << indent() << "}," << endl;
+  }
+
+  // application error
+  string app_err_var("app_err");
+  f_gen_ << indent() << "thrift::Error::Application(" << app_err_var << ") => {" << endl;
+  indent_up();
+  render_sync_handler_failed_application_exception_branch(tfunc, app_err_var);
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  // default case
+  f_gen_ << indent() << "_ => {" << endl;
+  indent_up();
+  render_sync_handler_failed_default_exception_branch(tfunc);
+  indent_down();
+  f_gen_ << indent() << "}," << endl;
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_sync_handler_failed_user_exception_branch(t_function *tfunc) {
+  if (tfunc->get_xceptions() == NULL || tfunc->get_xceptions()->get_sorted_members().empty()) {
+    throw "cannot render user exception branches if no user exceptions defined";
+  }
+
+  const vector<t_field*> txceptions = tfunc->get_xceptions()->get_sorted_members();
+  vector<t_field*>::const_iterator xception_iter;
+  int branches_rendered = 0;
+
+  // run through all user-defined exceptions
+  for (xception_iter = txceptions.begin(); xception_iter != txceptions.end(); ++xception_iter) {
+    t_field* xception_field = (*xception_iter);
+
+    string if_statement(branches_rendered == 0 ? "if usr_err" : "} else if usr_err");
+    string exception_type(to_rust_type(xception_field->get_type()));
+    f_gen_ << indent() << if_statement << ".downcast_ref::<" << exception_type << ">().is_some() {" << endl;
+    indent_up();
+
+    f_gen_
+      << indent()
+      << "let err = usr_err.downcast::<" << exception_type << ">().expect(\"downcast already checked\");"
+      << endl;
+
+    // render the members of the return struct
+    ostringstream members;
+
+    bool has_result_variable = !(tfunc->is_oneway() || tfunc->get_returntype()->is_void());
+    if (has_result_variable) {
+      members << SERVICE_RESULT_VARIABLE << ": None, ";
+    }
+
+    vector<t_field*>::const_iterator xception_members_iter;
+    for(xception_members_iter = txceptions.begin(); xception_members_iter != txceptions.end(); ++xception_members_iter) {
+      t_field* member = (*xception_members_iter);
+      string member_name(rust_field_name(member));
+      if (member == xception_field) {
+        members << member_name << ": Some(*err), ";
+      } else {
+        members << member_name << ": None, ";
+      }
+    }
+
+    string member_string = members.str();
+    member_string.replace(member_string.size() - 2, 2, " "); // trim trailing comma
+
+    // now write out the return struct
+    f_gen_
+      << indent()
+      << "let ret_err = "
+      << service_call_result_struct_name(tfunc)
+      << "{ " << member_string << "};"
+      << endl;
+
+    f_gen_
+      << indent()
+      << "let message_ident = "
+      << "TMessageIdentifier::new("
+      << "\"" << tfunc->get_name() << "\", " // note: use *original* name
+      << "TMessageType::Reply, "
+      << "incoming_sequence_number);"
+      << endl;
+    f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl;
+    f_gen_ << indent() << "ret_err.write_to_out_protocol(o_prot)?;" << endl;
+    f_gen_ << indent() << "o_prot.write_message_end()?;" << endl;
+    f_gen_ << indent() << "o_prot.flush()" << endl;
+
+    indent_down();
+
+    branches_rendered++;
+  }
+
+  // the catch all, if somehow it was a user exception that we don't support
+  f_gen_ << indent() << "} else {" << endl;
+  indent_up();
+
+  // FIXME: same as default block below
+
+  f_gen_ << indent() << "let ret_err = {" << endl;
+  indent_up();
+  render_rift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "usr_err.description()");
+  indent_down();
+  f_gen_ << indent() << "};" << endl;
+  render_sync_handler_send_exception_response(tfunc, "ret_err");
+
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+}
+
+void t_rs_generator::render_sync_handler_failed_application_exception_branch(
+    t_function *tfunc,
+    const string &app_err_var
+) {
+  if (tfunc->is_oneway()) {
+    f_gen_ << indent() << "Err(thrift::Error::Application(" << app_err_var << "))" << endl;
+  } else {
+    render_sync_handler_send_exception_response(tfunc, app_err_var);
+  }
+}
+
+void t_rs_generator::render_sync_handler_failed_default_exception_branch(t_function *tfunc) {
+  f_gen_ << indent() << "let ret_err = {" << endl;
+  indent_up();
+  render_rift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "e.description()");
+  indent_down();
+  f_gen_ << indent() << "};" << endl;
+  if (tfunc->is_oneway()) {
+    f_gen_ << indent() << "Err(thrift::Error::Application(ret_err))" << endl;
+  } else {
+    render_sync_handler_send_exception_response(tfunc, "ret_err");
+  }
+}
+
+void t_rs_generator::render_sync_handler_send_exception_response(t_function *tfunc, const string &err_var) {
+  f_gen_
+      << indent()
+      << "let message_ident = TMessageIdentifier::new("
+      << "\"" << tfunc->get_name() << "\", " // note: use *original* name
+      << "TMessageType::Exception, "
+      << "incoming_sequence_number);"
+      << endl;
+  f_gen_ << indent() << "o_prot.write_message_begin(&message_ident)?;" << endl;
+  f_gen_ << indent() << "thrift::Error::write_application_error_to_out_protocol(&" << err_var << ", o_prot)?;" << endl;
+  f_gen_ << indent() << "o_prot.write_message_end()?;" << endl;
+  f_gen_ << indent() << "o_prot.flush()" << endl;
+}
+
+string t_rs_generator::handler_successful_return_struct(t_function* tfunc) {
+  int member_count = 0;
+  ostringstream return_struct;
+
+  return_struct << service_call_result_struct_name(tfunc) << " { ";
+
+  // actual return
+  if (!tfunc->get_returntype()->is_void()) {
+    return_struct << "result_value: Some(handler_return)";
+    member_count++;
+  }
+
+  // any user-defined exceptions
+  if (tfunc->get_xceptions() != NULL) {
+    t_struct* txceptions = tfunc->get_xceptions();
+    const vector<t_field*> members = txceptions->get_sorted_members();
+    vector<t_field*>::const_iterator members_iter;
+    for (members_iter = members.begin(); members_iter != members.end(); ++members_iter) {
+      t_field* xception_field = (*members_iter);
+      if (member_count > 0) { return_struct << ", "; }
+      return_struct << rust_field_name(xception_field) << ": None";
+      member_count++;
+    }
+  }
+
+  return_struct << " }";
+
+  return  return_struct.str();
+}
+
+//-----------------------------------------------------------------------------
+//
+// Utility
+//
+//-----------------------------------------------------------------------------
+
+void t_rs_generator::render_type_comment(const string& type_name) {
+  f_gen_ << "//" << endl;
+  f_gen_ << "// " << type_name << endl;
+  f_gen_ << "//" << endl;
+  f_gen_ << endl;
+}
+
+// NOTE: do *not* put in an extra newline after doc is generated.
+// This is because rust docs have to abut the line they're documenting.
+void t_rs_generator::render_rustdoc(t_doc* tdoc) {
+  if (!tdoc->has_doc()) {
+    return;
+  }
+
+  generate_docstring_comment(f_gen_, "", "///", tdoc->get_doc(), "");
+}
+
+void t_rs_generator::render_rift_error(
+  const string& error_kind,
+  const string& error_struct,
+  const string& sub_error_kind,
+  const string& error_message
+) {
+  f_gen_ << indent() << "Err(" << endl;
+  indent_up();
+  f_gen_ << indent() << "thrift::Error::" << error_kind << "(" << endl;
+  indent_up();
+  render_rift_error_struct(error_struct, sub_error_kind, error_message);
+  indent_down();
+  f_gen_ << indent() << ")" << endl;
+  indent_down();
+  f_gen_ << indent() << ")" << endl;
+}
+
+void t_rs_generator::render_rift_error_struct(
+  const string& error_struct,
+  const string& sub_error_kind,
+  const string& error_message
+) {
+  f_gen_ << indent() << error_struct << "::new(" << endl;
+  indent_up();
+  f_gen_ << indent() << sub_error_kind << "," << endl;
+  f_gen_ << indent() << error_message << endl;
+  indent_down();
+  f_gen_ << indent() << ")" << endl;
+}
+
+string t_rs_generator::to_rust_type(t_type* ttype, bool ordered_float) {
+  // ttype = get_true_type(ttype); <-- recurses through as many typedef layers as necessary
+  if (ttype->is_base_type()) {
+    t_base_type* tbase_type = ((t_base_type*)ttype);
+    switch (tbase_type->get_base()) {
+    case t_base_type::TYPE_VOID:
+      return "()";
+    case t_base_type::TYPE_STRING:
+      if (tbase_type->is_binary()) {
+        return "Vec<u8>";
+      } else {
+        return "String";
+      }
+    case t_base_type::TYPE_BOOL:
+      return "bool";
+    case t_base_type::TYPE_I8:
+      return "i8";
+    case t_base_type::TYPE_I16:
+      return "i16";
+    case t_base_type::TYPE_I32:
+      return "i32";
+    case t_base_type::TYPE_I64:
+      return "i64";
+    case t_base_type::TYPE_DOUBLE:
+      if (ordered_float) {
+        return "OrderedFloat<f64>";
+      } else {
+        return "f64";
+      }
+    }
+  } else if (ttype->is_typedef()) {
+    return rust_namespace(ttype) + ((t_typedef*)ttype)->get_symbolic();
+  } else if (ttype->is_enum()) {
+    return rust_namespace(ttype) + ttype->get_name();
+  } else if (ttype->is_struct() || ttype->is_xception()) {
+    return rust_namespace(ttype) + rust_camel_case(ttype->get_name());
+  } else if (ttype->is_map()) {
+    t_map* tmap = (t_map*)ttype;
+    return "BTreeMap<" + to_rust_type(tmap->get_key_type()) + ", " + to_rust_type(tmap->get_val_type()) + ">";
+  } else if (ttype->is_set()) {
+    t_set* tset = (t_set*)ttype;
+    return "BTreeSet<" + to_rust_type(tset->get_elem_type()) + ">";
+  } else if (ttype->is_list()) {
+    t_list* tlist = (t_list*)ttype;
+    return "Vec<" + to_rust_type(tlist->get_elem_type()) + ">";
+  }
+
+  throw "cannot find rust type for " + ttype->get_name();
+}
+
+string t_rs_generator::to_rust_field_type_enum(t_type* ttype) {
+  ttype = get_true_type(ttype);
+  if (ttype->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
+    switch (tbase) {
+    case t_base_type::TYPE_VOID:
+      throw "will not generate protocol::TType for TYPE_VOID";
+    case t_base_type::TYPE_STRING: // both strings and binary are actually encoded as TType::String
+      return "TType::String";
+    case t_base_type::TYPE_BOOL:
+      return "TType::Bool";
+    case t_base_type::TYPE_I8:
+      return "TType::I08";
+    case t_base_type::TYPE_I16:
+      return "TType::I16";
+    case t_base_type::TYPE_I32:
+      return "TType::I32";
+    case t_base_type::TYPE_I64:
+      return "TType::I64";
+    case t_base_type::TYPE_DOUBLE:
+      return "TType::Double";
+    }
+  } else if (ttype->is_enum()) {
+    return "TType::I32";
+  } else if (ttype->is_struct() || ttype->is_xception()) {
+    return "TType::Struct";
+  } else if (ttype->is_map()) {
+    return "TType::Map";
+  } else if (ttype->is_set()) {
+    return "TType::Set";
+  } else if (ttype->is_list()) {
+    return "TType::List";
+  }
+
+  throw "cannot find TType for " + ttype->get_name();
+}
+
+string t_rs_generator::opt_in_req_out_value(t_type* ttype) {
+  ttype = get_true_type(ttype);
+  if (ttype->is_base_type()) {
+    t_base_type* tbase_type = ((t_base_type*)ttype);
+    switch (tbase_type->get_base()) {
+    case t_base_type::TYPE_VOID:
+      throw "cannot generate OPT_IN_REQ_OUT value for void";
+    case t_base_type::TYPE_STRING:
+      if (tbase_type->is_binary()) {
+        return "Some(Vec::new())";
+      } else {
+        return "Some(\"\".to_owned())";
+      }
+    case t_base_type::TYPE_BOOL:
+      return "Some(false)";
+    case t_base_type::TYPE_I8:
+    case t_base_type::TYPE_I16:
+    case t_base_type::TYPE_I32:
+    case t_base_type::TYPE_I64:
+      return "Some(0)";
+    case t_base_type::TYPE_DOUBLE:
+      return "Some(OrderedFloat::from(0.0))";
+    }
+
+  } else if (ttype->is_enum() || ttype->is_struct() || ttype->is_xception()) {
+    return "None";
+  } else if (ttype->is_list()) {
+    return "Some(Vec::new())";
+  } else if (ttype->is_set()) {
+    return "Some(BTreeSet::new())";
+  } else if (ttype->is_map()) {
+    return "Some(BTreeMap::new())";
+  }
+
+  throw "cannot generate opt-in-req-out value for type " + ttype->get_name();
+}
+
+bool t_rs_generator::can_generate_simple_const(t_type* ttype) {
+  t_type* actual_type = get_true_type(ttype);
+  if (actual_type->is_base_type()) {
+    t_base_type* tbase_type = (t_base_type*)actual_type;
+    return !(tbase_type->get_base() == t_base_type::TYPE_DOUBLE);
+  } else {
+    return false;
+  }
+}
+
+bool t_rs_generator::can_generate_const_holder(t_type* ttype) {
+  t_type* actual_type = get_true_type(ttype);
+  return !can_generate_simple_const(actual_type) && !actual_type->is_service();
+}
+
+bool t_rs_generator::is_void(t_type* ttype) {
+  return ttype->is_base_type() && ((t_base_type*)ttype)->get_base() == t_base_type::TYPE_VOID;
+}
+
+bool t_rs_generator::is_optional(t_field::e_req req) {
+  return req == t_field::T_OPTIONAL || req == t_field::T_OPT_IN_REQ_OUT;
+}
+
+t_field::e_req t_rs_generator::actual_field_req(t_field* tfield, t_rs_generator::e_struct_type struct_type) {
+  return struct_type == t_rs_generator::T_ARGS ? t_field::T_REQUIRED : tfield->get_req();
+}
+
+bool t_rs_generator::has_args(t_function* tfunc) {
+  return tfunc->get_arglist() != NULL && !tfunc->get_arglist()->get_sorted_members().empty();
+}
+
+bool t_rs_generator::has_non_void_args(t_function* tfunc) {
+  bool has_non_void_args = false;
+
+  const vector<t_field*> args = tfunc->get_arglist()->get_sorted_members();
+  vector<t_field*>::const_iterator args_iter;
+  for (args_iter = args.begin(); args_iter != args.end(); ++args_iter) {
+    t_field* tfield = (*args_iter);
+    if (!tfield->get_type()->is_void()) {
+      has_non_void_args = true;
+      break;
+    }
+  }
+
+  return has_non_void_args;
+}
+
+string t_rs_generator::visibility_qualifier(t_rs_generator::e_struct_type struct_type) {
+  switch(struct_type) {
+  case t_rs_generator::T_ARGS:
+  case t_rs_generator::T_RESULT:
+    return "";
+  default:
+    return "pub ";
+  }
+}
+
+string t_rs_generator::rust_namespace(t_service* tservice) {
+  if (tservice->get_program()->get_name() != get_program()->get_name()) {
+    return rust_snake_case(tservice->get_program()->get_name()) + "::";
+  } else {
+    return "";
+  }
+}
+
+string t_rs_generator::rust_namespace(t_type* ttype) {
+  if (ttype->get_program()->get_name() != get_program()->get_name()) {
+    return rust_snake_case(ttype->get_program()->get_name()) + "::";
+  } else {
+    return "";
+  }
+}
+
+bool t_rs_generator::is_reserved(const string& name) {
+  return RUST_RESERVED_WORDS_SET.find(name) != RUST_RESERVED_WORDS_SET.end();
+}
+
+string t_rs_generator::rust_struct_name(t_struct* tstruct) {
+  string base_struct_name(rust_camel_case(tstruct->get_name()));
+  return rust_safe_name(base_struct_name);
+}
+
+string t_rs_generator::rust_field_name(t_field* tfield) {
+  string base_field_name(rust_snake_case(tfield->get_name()));
+  return rust_safe_name(base_field_name);
+}
+
+string t_rs_generator::rust_union_field_name(t_field* tfield) {
+  string base_field_name(rust_camel_case(tfield->get_name()));
+  return rust_safe_name(base_field_name);
+}
+
+string t_rs_generator::rust_safe_name(const string& name) {
+  if (is_reserved(name)) {
+    return name + "_";
+  } else {
+    return name;
+  }
+}
+
+string t_rs_generator::service_call_client_function_name(t_function* tfunc) {
+  return rust_snake_case(tfunc->get_name());
+}
+
+string t_rs_generator::service_call_handler_function_name(t_function* tfunc) {
+  return "handle_" + rust_snake_case(tfunc->get_name());
+}
+
+string t_rs_generator::service_call_result_struct_name(t_function* tfunc) {
+  return rust_camel_case(tfunc->get_name()) + RESULT_STRUCT_SUFFIX;
+}
+
+string t_rs_generator::rust_sync_client_marker_trait_name(t_service* tservice) {
+  return "T" + rust_camel_case(tservice->get_name()) + "SyncClientMarker";
+}
+
+string t_rs_generator::rust_sync_client_trait_name(t_service* tservice) {
+  return "T" + rust_camel_case(tservice->get_name()) + "SyncClient";
+}
+
+string t_rs_generator::rust_sync_client_impl_name(t_service* tservice) {
+  return rust_camel_case(tservice->get_name()) + "SyncClient";
+}
+
+string t_rs_generator::rust_sync_handler_trait_name(t_service* tservice) {
+  return rust_camel_case(tservice->get_name()) + "SyncHandler";
+}
+
+string t_rs_generator::rust_sync_processor_name(t_service* tservice) {
+  return rust_camel_case(tservice->get_name()) + "SyncProcessor";
+}
+
+string t_rs_generator::rust_sync_processor_impl_name(t_service *tservice) {
+  return "T" + rust_camel_case(tservice->get_name()) + "ProcessFunctions";
+}
+
+string t_rs_generator::rust_upper_case(const string& name) {
+  string str(uppercase(underscore(name)));
+  string_replace(str, "__", "_");
+  return str;
+}
+
+string t_rs_generator::rust_snake_case(const string& name) {
+  string str(decapitalize(underscore(name)));
+  string_replace(str, "__", "_");
+  return str;
+}
+
+string t_rs_generator::rust_camel_case(const string& name) {
+  string str(capitalize(camelcase(name)));
+  string_replace(str, "_", "");
+  return str;
+}
+
+void t_rs_generator::string_replace(string& target, const string& search_string, const string& replace_string) {
+  if (target.empty()) {
+    return;
+  }
+
+  size_t match_len = search_string.length();
+  size_t replace_len = replace_string.length();
+
+  size_t search_idx = 0;
+  size_t match_idx;
+  while ((match_idx = target.find(search_string, search_idx)) != string::npos) {
+    target.replace(match_idx, match_len, replace_string);
+    search_idx = match_idx + replace_len;
+  }
+}
+
+THRIFT_REGISTER_GENERATOR(
+  rs,
+  "Rust",
+  "\n") // no Rust-generator-specific options
