diff --git a/src/mako/lib.rs.mako b/src/mako/lib.rs.mako index 2a3a09addfb..3005da61698 100644 --- a/src/mako/lib.rs.mako +++ b/src/mako/lib.rs.mako @@ -36,7 +36,7 @@ extern crate "yup-oauth2" as oauth2; extern crate mime; extern crate url; -pub mod cmn; +mod cmn; use std::collections::HashMap; use std::cell::RefCell; @@ -49,7 +49,7 @@ use std::io; use std::fs; use std::old_io::timer::sleep; -use cmn::{Hub, ReadSeek, Part, ResponseResult, RequestValue, NestedType, Delegate, DefaultDelegate}; +pub use cmn::{MultiPartReader, MethodInfo, Result, MethodBuilder, Hub, ReadSeek, Part, ResponseResult, RequestValue, NestedType, Delegate, DefaultDelegate}; // ############## diff --git a/src/mako/lib/lib.mako b/src/mako/lib/lib.mako index 981d5940636..33f41510340 100644 --- a/src/mako/lib/lib.mako +++ b/src/mako/lib/lib.mako @@ -5,7 +5,7 @@ find_fattest_resource, build_all_params, pass_through, parts_from_params, REQUEST_MARKER_TRAIT, RESPONSE_MARKER_TRAIT, supports_scopes, to_api_version, to_fqan, METHODS_RESOURCE, ADD_PARAM_MEDIA_EXAMPLE, PROTOCOL_TYPE_INFO, enclose_in, - upload_action_fn) %>\ + upload_action_fn, unique_type_name) %>\ <%namespace name="util" file="util.mako"/>\ <%namespace name="mbuild" file="mbuild.mako"/>\ @@ -78,7 +78,7 @@ It seems there is nothing you can do here ... . sn = singular(canonical_type_name(r)) if sn in schemas: - md_resource = link(md_resource, 'struct.%s.html' % singular(canonical_type_name(r))) + md_resource = link(md_resource, 'struct.%s.html' % unique_type_name(singular(canonical_type_name(r)))) %>\ * ${md_resource} (${put_and(md_methods)}) % endfor ## each resource activity diff --git a/src/mako/lib/mbuild.mako b/src/mako/lib/mbuild.mako index b98e20a9d8a..96c8d9e956e 100644 --- a/src/mako/lib/mbuild.mako +++ b/src/mako/lib/mbuild.mako @@ -10,7 +10,7 @@ METHOD_BUILDER_MARKERT_TRAIT, pass_through, markdown_rust_block, parts_from_params, DELEGATE_PROPERTY_NAME, struct_type_bounds_s, supports_scopes, scope_url_to_variant, re_find_replacements, ADD_PARAM_FN, ADD_PARAM_MEDIA_EXAMPLE, upload_action_fn, METHODS_RESOURCE, - method_name_to_variant) + method_name_to_variant, unique_type_name) def get_parts(part_prop): if not part_prop: @@ -67,7 +67,7 @@ ${m.description | rust_doc_comment} /// `${ADD_PARAM_MEDIA_EXAMPLE}`. % if response_schema: /// Please note that due to missing multi-part support on the server side, you will only receive the media, -/// but not the `${response_schema.id}` structure that you would usually get. The latter will be a default value. +/// but not the `${unique_type_name(response_schema.id)}` structure that you would usually get. The latter will be a default value. % endif /// % endif ## supports media download @@ -125,7 +125,7 @@ pub struct ${ThisType} % endif } -impl${mb_tparams} cmn::${METHOD_BUILDER_MARKERT_TRAIT} for ${ThisType} {} +impl${mb_tparams} ${METHOD_BUILDER_MARKERT_TRAIT} for ${ThisType} {} impl${mb_tparams} ${ThisType} where ${', '.join(mb_type_bounds())} { @@ -297,14 +297,17 @@ ${self._setter_fn(resource, method, m, p, part_prop, ThisType, c)}\ hide_filter = show_all and pass_through or hide_rust_doc_test test_block_filter = rust_doc and rust_doc_test_norun or markdown_rust_block test_fn_filter = rust_doc and rust_test_fn_invisible or pass_through + + if request_value: + request_value_type = unique_type_name(request_value.id) %>\ <%block filter="test_block_filter">\ ${capture(util.test_prelude) | hide_filter}\ % if request_value: -use ${util.library_name()}::${request_value.id}; +use ${util.library_name()}::${request_value_type}; % endif % if handle_result: -use ${util.library_name()}::cmn::Result; +use ${util.library_name()}::Result; % endif % if media_params: use std::fs; @@ -315,7 +318,7 @@ ${capture(lib.test_hub, hub_type_name, comments=show_all) | hide_filter} // As the method needs a request, you would usually fill it with the desired information // into the respective structure. Some of the parts shown here might not be applicable ! // ${random_value_warning} -let mut ${rb_name}: ${request_value.id} = Default::default(); +let mut ${rb_name}: ${request_value_type} = Default::default(); % for spn, sp in request_value.get('properties', dict()).iteritems(): % if parts is not None and spn not in parts: <% continue %> @@ -331,7 +334,6 @@ let mut ${rb_name}: ${request_value.id} = Default::default(); else: assignment = 'Some(%s);' % assignment %>\ -## ${to_rust_type(request_value.id, spn, sp, allow_optionals=False)} ${rb_name}.${mangle_ident(spn)} = ${assignment} % endfor @@ -382,7 +384,7 @@ match result { where = '' qualifier = 'pub ' add_args = '' - rtype = 'cmn::Result' + rtype = 'Result' response_schema = method_response(c, m) supports_download = m.get('supportsMediaDownload', False); @@ -390,7 +392,7 @@ match result { if response_schema: if not supports_download: reserved_params = ['alt'] - rtype = 'cmn::Result<(hyper::client::Response, %s)>' % (response_schema.id) + rtype = 'Result<(hyper::client::Response, %s)>' % (unique_type_name(response_schema.id)) mtype_param = 'RS' mtype_where = 'ReadSeek' @@ -482,7 +484,7 @@ match result { use std::io::{Read, Seek}; use hyper::header::{ContentType, ContentLength, Authorization, UserAgent}; if let Some(ref mut d) = ${delegate} { - d.begin(cmn::MethodInfo { id: "${m.id}", + d.begin(MethodInfo { id: "${m.id}", http_method: ${method_name_to_variant(m.httpMethod)} }); } let mut params: Vec<(&str, String)> = Vec::with_capacity((${len(params) + len(reserved_params)} + ${paddfields}.len())); @@ -522,7 +524,7 @@ match result { for &field in [${', '.join(enclose_in('"', reserved_params + [p.name for p in field_params]))}].iter() { if ${paddfields}.contains_key(field) { ${delegate_finish} - return cmn::Result::FieldClash(field); + return Result::FieldClash(field); } } for (name, value) in ${paddfields}.iter() { @@ -584,7 +586,7 @@ else { Some(value) => params.push(("key", value)), None => { ${delegate_finish} - return cmn::Result::MissingAPIKey + return Result::MissingAPIKey } } % else: @@ -658,7 +660,7 @@ else { }} if token.is_none() { ${delegate_finish} - return cmn::Result::MissingToken + return Result::MissingToken } let auth_header = Authorization(token.unwrap().access_token); % endif @@ -666,7 +668,7 @@ else { request_value_reader.seek(io::SeekFrom::Start(0)).unwrap(); % endif % if request_value and simple_media_param: - let mut mp_reader: cmn::MultiPartReader = Default::default(); + let mut mp_reader: MultiPartReader = Default::default(); let (mut body_reader, content_type) = match ${simple_media_param.type.arg_name}.as_mut() { Some(&mut (ref mut reader, ref mime)) => { mp_reader.reserve_exact(2); @@ -721,7 +723,7 @@ else { } } ${delegate_finish} - return cmn::Result::HttpError(err) + return Result::HttpError(err) } Ok(mut res) => { if !res.status.is_success() { @@ -735,7 +737,7 @@ else { } } ${delegate_finish} - return cmn::Result::Failure(res) + return Result::Failure(res) } % if response_schema: ## If 'alt' is not json, we cannot attempt to decode the response @@ -756,7 +758,7 @@ if enable_resource_parsing \ let result_value = res; % endif ${delegate_finish} - return cmn::Result::Success(result_value) + return Result::Success(result_value) } } } diff --git a/src/mako/lib/schema.mako b/src/mako/lib/schema.mako index b7b4319efcc..b12593903cc 100644 --- a/src/mako/lib/schema.mako +++ b/src/mako/lib/schema.mako @@ -1,7 +1,7 @@ <%! from util import (schema_markers, rust_doc_comment, mangle_ident, to_rust_type, put_and, IO_TYPES, activity_split, enclose_in, REQUEST_MARKER_TRAIT, mb_type, indent_all_but_first_by, - NESTED_TYPE_SUFFIX, RESPONSE_MARKER_TRAIT, split_camelcase_s, METHODS_RESOURCE) + NESTED_TYPE_SUFFIX, RESPONSE_MARKER_TRAIT, split_camelcase_s, METHODS_RESOURCE, unique_type_name) default_traits = ('RustcEncodable', 'Clone', 'Default') %>\ @@ -9,7 +9,7 @@ ################################################################################################################### ################################################################################################################### <%def name="_new_object(s, properties, c)">\ -<% struct = 'pub struct ' + s.id %>\ +<% struct = 'pub struct ' + unique_type_name(s.id) %>\ % if properties: ${struct} { % for pn, p in properties.iteritems(): @@ -41,6 +41,8 @@ ${struct}; ## waiting for Default: https://github.com/rust-lang/rustc-serialize/issues/71 if s.type == 'any': traits.remove('Default') + + s_type = unique_type_name(s.id) %>\ <%block filter="rust_doc_comment">\ ${doc(s, c)}\ @@ -50,17 +52,17 @@ ${doc(s, c)}\ ${_new_object(s, s.get('properties'), c)}\ % elif s.type == 'array': % if s.items.get('type') != 'object': -pub struct ${s.id}(${to_rust_type(schemas, s.id, NESTED_TYPE_SUFFIX, s)}); +pub struct ${s_type}(${to_rust_type(schemas, s.id, NESTED_TYPE_SUFFIX, s)}); % else: ${_new_object(s, s.items.get('properties'), c)}\ % endif ## array item != 'object' % elif s.type == 'any': ## waiting for Default: https://github.com/rust-lang/rustc-serialize/issues/71 -pub struct ${s.id}(rustc_serialize::json::Json); +pub struct ${s_type}(rustc_serialize::json::Json); -impl Default for ${s.id} { - fn default() -> ${s.id} { - ${s.id}(rustc_serialize::json::Json::Null) +impl Default for ${s_type} { + fn default() -> ${s_type} { + ${s_type}(rustc_serialize::json::Json::Null) } } % else: @@ -68,11 +70,11 @@ impl Default for ${s.id} { % endif ## type == ? % for marker_trait in markers: -impl ${marker_trait} for ${s.id} {} +impl ${marker_trait} for ${s_type} {} % endfor % if REQUEST_MARKER_TRAIT in markers and 'properties' in s: -impl ${s.id} { +impl ${s_type} { /// Return a comma separated list of members that are currently set, i.e. for which `self.member.is_some()`. /// The produced string is suitable for use as a parts list that indicates the parts you are sending, and/or /// the parts you want to see in the server response. diff --git a/src/mako/lib/util.py b/src/mako/lib/util.py index 82664d7d29a..24010994cab 100644 --- a/src/mako/lib/util.py +++ b/src/mako/lib/util.py @@ -35,6 +35,7 @@ 'return', 'sizeof', 'static', 'self', 'struct', 'super', 'true', 'trait', 'type', 'typeof', 'unsafe', 'unsized', 'use', 'virtual', 'where', 'while', 'yield')) +RESERVED_TYPES = set(("Result", )) _words = [w.strip(',') for w in "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.".split(' ')] RUST_TYPE_RND_MAP = {'bool': lambda: str(bool(randint(0, 1))).lower(), @@ -283,7 +284,7 @@ def _assure_unique_type_name(schemas, tn): if tn in schemas: tn += 'Nested' assert tn not in schemas - return tn + return unique_type_name(tn) # map a json type to an rust type # sn = schema name @@ -305,7 +306,7 @@ def nested_type(nt): def wrap_type(tn): if allow_optionals: tn = "Option<%s>" % tn - return tn + return unique_type_name(tn) # unconditionally handle $ref types, which should point to another schema. if TREF in t: @@ -314,7 +315,7 @@ def wrap_type(tn): # usually is on on the first call, and off when recursion is involved. tn = t[TREF] if allow_optionals and tn == sn: - tn = 'Box<%s>' % tn + tn = 'Box<%s>' % unique_type_name(tn) return wrap_type(tn) try: rust_type = TYPE_MAP[t.type] @@ -799,6 +800,12 @@ def mb_type_params_s(m): def mb_additional_type_params(m): return [] +# check type_name against a list of reserved types, and return a possibly rename type_name to prevent a clash +def unique_type_name(type_name): + if type_name in RESERVED_TYPES: + type_name += 'Type' + return type_name + # return type name for a method on the given resource def mb_type(r, m): return "%s%sMethodBuilder" % (singular(canonical_type_name(r)), dot_sep_to_canonical_type_name(m))