mirror of
https://github.com/OMGeeky/google-apis-rs.git
synced 2026-01-21 10:38:25 +01:00
feat(builders): request type handling part 1
Now we will generate proper resoure methods builder calls to instaniate the more or less valid method builders. However, it doesn't compile yet, and the 'to_parts()' method on resources is still missing.
This commit is contained in:
@@ -21,7 +21,7 @@ pub trait Resource: MarkerTrait {}
|
||||
pub trait ResponseResult: MarkerTrait {}
|
||||
|
||||
/// Identifies types which are used in API requests.
|
||||
pub trait RequestResult: MarkerTrait {}
|
||||
pub trait RequestValue: MarkerTrait {}
|
||||
|
||||
/// Identifies types which are only used as part of other types, which
|
||||
/// usually are carrying the `Resource` trait.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,8 @@
|
||||
from util import (put_and, rust_test_fn_invisible, rust_doc_test_norun, rust_doc_comment,
|
||||
rb_type, mb_type, singular, hub_type, to_fqan, indent_all_but_first_by,
|
||||
method_params, activity_rust_type, mangle_ident, activity_input_type, get_word,
|
||||
split_camelcase_s, property, is_pod_property, TREF)
|
||||
split_camelcase_s, property, is_pod_property, TREF, method_io, IO_REQUEST,
|
||||
RESOURCE_MARKER, schema_to_required_property, rust_copy_value_s, is_required_property)
|
||||
%>\
|
||||
<%namespace name="util" file="util.mako"/>\
|
||||
<%namespace name="lib" file="lib.mako"/>\
|
||||
@@ -16,6 +17,11 @@
|
||||
m = c.fqan_map[to_fqan(name, resource, method)]
|
||||
# an identifier for a property. We prefix them to prevent clashes with the setters
|
||||
ThisType = mb_type(resource, method) + "<'a, C, NC, A>"
|
||||
|
||||
request_resource = method_io(schemas, c, m, IO_REQUEST, RESOURCE_MARKER)
|
||||
params = method_params(m)
|
||||
if request_resource:
|
||||
params.insert(0, schema_to_required_property(request_resource, 'request'))
|
||||
%>\
|
||||
% if 'description' in m:
|
||||
${m.description | rust_doc_comment}
|
||||
@@ -51,8 +57,13 @@ pub struct ${ThisType}
|
||||
|
||||
hub: &'a ${hub_type_name}<C, NC, A>,
|
||||
## PROPERTIES ###############
|
||||
% for p in method_params(m):
|
||||
${property(p.name)}: ${activity_rust_type(p)},
|
||||
% for p in params:
|
||||
${property(p.name)}:\
|
||||
% if is_required_property(p):
|
||||
${activity_rust_type(p, allow_optionals=False)},
|
||||
% else:
|
||||
${activity_rust_type(p)},
|
||||
% endif
|
||||
% endfor
|
||||
}
|
||||
|
||||
@@ -68,7 +79,7 @@ impl<'a, C, NC, A> ${ThisType} {
|
||||
}
|
||||
|
||||
## SETTERS ###############
|
||||
% for p in method_params(m):
|
||||
% for p in params:
|
||||
${self._setter(resource, method, m, p, ThisType, c)}\
|
||||
% endfor
|
||||
}
|
||||
@@ -90,11 +101,9 @@ ${self._setter(resource, method, m, p, ThisType, c)}\
|
||||
return m.request.get(TREF, 'first') == m.response.get(TREF, 'second')
|
||||
|
||||
value_name = 'new_value'
|
||||
new_value_copied = value_name + '.clone()'
|
||||
if InType == '&str':
|
||||
new_value_copied = value_name + '.to_string()'
|
||||
elif is_pod_property(p):
|
||||
new_value_copied = value_name
|
||||
new_value_copied = rust_copy_value_s(value_name, InType, p)
|
||||
if not is_required_property(p):
|
||||
new_value_copied = 'Some(%s)' % new_value_copied
|
||||
%>\
|
||||
/// Sets the *${split_camelcase_s(p.name)}* ${get_word(p, 'location')}property to the given value.
|
||||
///
|
||||
@@ -104,7 +113,7 @@ ${self._setter(resource, method, m, p, ThisType, c)}\
|
||||
/// This may not always be desirable, as you can obtain (newly generated) parts you cannot pass in,
|
||||
/// like statistics that are generated server side. Therefore you should use this method to specify
|
||||
/// the parts you provide in addition to the ones you want in the response.
|
||||
% elif p.get('required', False):
|
||||
% elif is_required_property(p):
|
||||
/// Even though the property as already been set when instantiating this call,
|
||||
/// we provide this method for API completeness.
|
||||
% endif
|
||||
@@ -113,7 +122,7 @@ ${self._setter(resource, method, m, p, ThisType, c)}\
|
||||
${p.description | rust_doc_comment, indent_all_but_first_by(1)}
|
||||
% endif
|
||||
pub fn ${mangle_ident(p.name)}(&mut self, ${value_name}: ${InType}) -> &mut ${ThisType} {
|
||||
self.${property(p.name)} = Some(${new_value_copied});
|
||||
self.${property(p.name)} = ${new_value_copied};
|
||||
return self;
|
||||
}
|
||||
</%def>
|
||||
@@ -1,7 +1,9 @@
|
||||
<%!
|
||||
from util import (put_and, rust_test_fn_invisible, rust_doc_test_norun, rust_doc_comment,
|
||||
rb_type, singular, hub_type, mangle_ident, mb_type, method_params, property,
|
||||
to_fqan, indent_all_but_first_by)
|
||||
to_fqan, indent_all_but_first_by, RESOURCE_MARKER, schema_markers,
|
||||
activity_input_type, TREF, method_io, IO_REQUEST, schema_to_required_property,
|
||||
rust_copy_value_s, is_required_property)
|
||||
%>\
|
||||
<%namespace name="util" file="util.mako"/>\
|
||||
<%namespace name="lib" file="lib.mako"/>\
|
||||
@@ -49,6 +51,33 @@ impl<'a, C, NC, A> ${ThisType} {
|
||||
<%
|
||||
m = c.fqan_map[to_fqan(name, resource, a)]
|
||||
RType = mb_type(resource, a)
|
||||
|
||||
# skip part if we have a request resource. Only resources can have parts
|
||||
# that we can easily deduce
|
||||
request_resource = method_io(schemas, c, m, IO_REQUEST, RESOURCE_MARKER)
|
||||
params = method_params(m)
|
||||
REQUEST_RESOURCE_PROPERTY_NAME = 'request'
|
||||
if request_resource:
|
||||
# resource into property
|
||||
resprop = schema_to_required_property(request_resource, REQUEST_RESOURCE_PROPERTY_NAME)
|
||||
params.insert(0, resprop)
|
||||
|
||||
part_prop = None
|
||||
optional_props = list()
|
||||
required_props = list()
|
||||
for p in params:
|
||||
if is_required_property(p):
|
||||
if request_resource and p.name == 'part':
|
||||
part_prop = p
|
||||
else:
|
||||
required_props.append(p)
|
||||
else:
|
||||
optional_props.append(p)
|
||||
# end for each property
|
||||
|
||||
method_args = ''
|
||||
if required_props:
|
||||
method_args = ', ' + ', '.join('%s: %s' % (mangle_ident(p.name), activity_input_type(p)) for p in required_props)
|
||||
%>\
|
||||
|
||||
% if 'description' in m:
|
||||
@@ -56,10 +85,17 @@ impl<'a, C, NC, A> ${ThisType} {
|
||||
///
|
||||
${m.description | rust_doc_comment, indent_all_but_first_by(1)}
|
||||
% endif
|
||||
pub fn ${mangle_ident(a)}(&self) -> ${RType}<'a, C, NC, A> {
|
||||
pub fn ${mangle_ident(a)}(&self${method_args}) -> ${RType}<'a, C, NC, A> {
|
||||
${RType} {
|
||||
hub: self.hub,
|
||||
% for p in method_params(m):
|
||||
% for p in required_props:
|
||||
${property(p.name)}: ${rust_copy_value_s(mangle_ident(p.name), activity_input_type(p), p)},
|
||||
% endfor
|
||||
## auto-generate parts from request resources
|
||||
% if part_prop and request_resource:
|
||||
${property(part_prop.name)}: ${mangle_ident(REQUEST_RESOURCE_PROPERTY_NAME)}.to_parts(),
|
||||
% endif
|
||||
% for p in optional_props:
|
||||
${property(p.name)}: Default::default(),
|
||||
% endfor
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ pub struct ${s.id}\
|
||||
% for marker_trait in markers:
|
||||
impl ${marker_trait} for ${s.id} {}
|
||||
% endfor
|
||||
|
||||
% if RESOURCE_MARKER in markers:
|
||||
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="doc(s, c)">\
|
||||
|
||||
@@ -24,6 +24,10 @@ DEL_METHOD = 'delete'
|
||||
NESTED_TYPE_MARKER = 'is_nested'
|
||||
SPACES_PER_TAB = 4
|
||||
|
||||
REQUEST_PRIORITY = 100
|
||||
REQUEST_MARKER = 'RequestValue'
|
||||
RESOURCE_MARKER = 'Resource'
|
||||
|
||||
# ==============================================================================
|
||||
## @name Filters
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -225,7 +229,7 @@ def activity_input_type(p):
|
||||
return '&%s' % n
|
||||
|
||||
def is_pod_property(p):
|
||||
return 'format' in p or p.type == 'boolean'
|
||||
return 'format' in p or p.get('type','') == 'boolean'
|
||||
|
||||
# return an iterator yielding fake-schemas that identify a nested type
|
||||
def iter_nested_types(schemas):
|
||||
@@ -252,11 +256,11 @@ def schema_markers(s, c):
|
||||
# it should have at least one activity that matches it's type to qualify for the Resource trait
|
||||
for fqan, iot in activities.iteritems():
|
||||
if activity_name_to_type_name(activity_split(fqan)[0]).lower() == s.id.lower():
|
||||
res.add('Resource')
|
||||
res.add(RESOURCE_MARKER)
|
||||
if IO_RESPONSE in iot:
|
||||
res.add('ResponseResult')
|
||||
if IO_REQUEST in iot:
|
||||
res.add('RequestResult')
|
||||
res.add(REQUEST_MARKER)
|
||||
# end for each activity
|
||||
# end handle activites
|
||||
|
||||
@@ -319,6 +323,32 @@ def method_params(m, required=None, location=None):
|
||||
# end for each parameter
|
||||
return sorted(res, key=lambda p: (p.priority, p.name), reverse=True)
|
||||
|
||||
# return the given method's request or response schema (dict), or None.
|
||||
# optionally return only schemas with the given marker trait
|
||||
def method_io(schemas, c, m, type, marker=None):
|
||||
s = schemas.get(m.get('request', dict()).get(TREF))
|
||||
if s is None:
|
||||
return s
|
||||
if s and marker and marker not in schema_markers(s, c):
|
||||
return None
|
||||
return s
|
||||
|
||||
# return string like 'n.clone()', but depending on the type name of tn (e.g. &str -> n.to_string())
|
||||
def rust_copy_value_s(n, tn, p):
|
||||
nc = n + '.clone()'
|
||||
if tn == '&str':
|
||||
nc = n + '.to_string()'
|
||||
elif is_pod_property(p):
|
||||
nc = n
|
||||
return nc
|
||||
|
||||
# convert a schema into a property (for use with rust type generation).
|
||||
# n = name of the property
|
||||
def schema_to_required_property(s, n):
|
||||
return type(s)({'name': n, TREF: s.id, 'priority': REQUEST_PRIORITY})
|
||||
|
||||
def is_required_property(p):
|
||||
return p.get('required', False) or p.get('priority', 0) > 0
|
||||
|
||||
## -- End Activity Utilities -- @}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ pub trait Resource: MarkerTrait {}
|
||||
pub trait ResponseResult: MarkerTrait {}
|
||||
|
||||
/// Identifies types which are used in API requests.
|
||||
pub trait RequestResult: MarkerTrait {}
|
||||
pub trait RequestValue: MarkerTrait {}
|
||||
|
||||
/// Identifies types which are only used as part of other types, which
|
||||
/// usually are carrying the `Resource` trait.
|
||||
|
||||
Reference in New Issue
Block a user