mirror of
https://github.com/OMGeeky/google-apis-rs.git
synced 2026-02-23 15:49:49 +01:00
refactor(engine): request-value parsing;Default
* Default::default() optimized to use T::default() if possible
* deduplicated special type handling ('Count' strings -> int64)
* put request value parsing into own private function
Fixes #69
[skip ci]
This commit is contained in:
@@ -108,13 +108,18 @@ def call_method_ident(resource, method):
|
||||
def subcommand_md_filename(resource, method):
|
||||
return mangle_subcommand(resource) + '_' + mangle_subcommand(method) + '.md'
|
||||
|
||||
|
||||
def docopt_mode(protocols):
|
||||
mode = '|'.join(protocols)
|
||||
if len(protocols) > 1:
|
||||
mode = '(%s)' % mode
|
||||
return mode
|
||||
|
||||
# Returns a possibly remapped type, based on its name.
|
||||
# Useful to map strings to more suitable types, i.e. counts
|
||||
def actual_json_type(name, type):
|
||||
if type == 'string' and 'Count' in name:
|
||||
return 'int64'
|
||||
return type
|
||||
|
||||
# Return schema' with fields dict: { 'field1' : SchemaField(...), 'SubSchema': schema' }
|
||||
def to_cli_schema(c, schema):
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
from cli import (mangle_subcommand, new_method_context, PARAM_FLAG, STRUCT_FLAG, UPLOAD_FLAG, OUTPUT_FLAG, VALUE_ARG,
|
||||
CONFIG_DIR, SCOPE_FLAG, is_request_value_property, FIELD_SEP, docopt_mode, FILE_ARG, MIME_ARG, OUT_ARG,
|
||||
cmd_ident, call_method_ident, arg_ident, POD_TYPES, flag_ident, ident, JSON_TYPE_VALUE_MAP,
|
||||
KEY_VALUE_ARG, to_cli_schema, SchemaEntry, CTYPE_POD)
|
||||
KEY_VALUE_ARG, to_cli_schema, SchemaEntry, CTYPE_POD, actual_json_type)
|
||||
|
||||
v_arg = '<%s>' % VALUE_ARG
|
||||
SOPT = 'self.opt.'
|
||||
@@ -160,7 +160,7 @@ self.opt.${cmd_ident(method)} {
|
||||
%>\
|
||||
% if is_request_value_property(mc, p):
|
||||
<% request_prop_type = prop_type %>\
|
||||
let mut ${prop_name}: api::${prop_type} = Default::default();
|
||||
let mut ${prop_name} = api::${prop_type}::default();
|
||||
% elif p.type != 'string':
|
||||
let ${prop_name}: ${prop_type} = arg_from_str(&${opt_ident}, err, "<${mangle_subcommand(p.name)}>", "${p.type}");
|
||||
% endif # handle request value
|
||||
@@ -187,9 +187,7 @@ for parg in ${SOPT + arg_ident(VALUE_ARG)}.iter() {
|
||||
match key {
|
||||
% for p in optional_props:
|
||||
<%
|
||||
ptype = p.type
|
||||
if p.type == 'string' and 'Count' in p.name:
|
||||
ptype = 'int64'
|
||||
ptype = actual_json_type(p.name, p.type)
|
||||
value_unwrap = 'value.unwrap_or("%s")' % JSON_TYPE_VALUE_MAP[ptype]
|
||||
%>\
|
||||
"${mangle_subcommand(p.name)}" => {
|
||||
@@ -240,112 +238,7 @@ ${value_unwrap}\
|
||||
}
|
||||
% endif # handle call parameters
|
||||
% if mc.request_value:
|
||||
<%
|
||||
allow_optionals_fn = lambda s: is_schema_with_optionals(schema_markers(s, c, transitive=False))
|
||||
|
||||
def flatten_schema_fields(schema, res, init_fn_map, cur=list(), init_call=None):
|
||||
if len(cur) == 0:
|
||||
init_call = ''
|
||||
cur = list()
|
||||
|
||||
opt_access = '.as_mut().unwrap()'
|
||||
allow_optionals = allow_optionals_fn(schema)
|
||||
parent_init_call = init_call
|
||||
if not allow_optionals:
|
||||
opt_access = ''
|
||||
for fn, f in schema.fields.iteritems():
|
||||
cur.append(['%s%s' % (mangle_ident(fn), opt_access), fn])
|
||||
if isinstance(f, SchemaEntry):
|
||||
cur[-1][0] = mangle_ident(fn)
|
||||
res.append((init_call, schema, f, list(cur)))
|
||||
else:
|
||||
if allow_optionals:
|
||||
init_fn_name = 'request_%s_init' % '_'.join(mangle_ident(t[1]) for t in cur)
|
||||
init_call = init_fn_name + '(&mut request);'
|
||||
struct_field = 'request.' + '.'.join('%s%s' % (mangle_ident(t[1]), opt_access) for t in cur[:-1])
|
||||
if len(cur) > 1:
|
||||
struct_field += '.'
|
||||
struct_field += mangle_ident(cur[-1][1])
|
||||
init_fn = "fn %s(request: &mut api::%s) {\n" % (init_fn_name, request_prop_type)
|
||||
if parent_init_call:
|
||||
pcall = parent_init_call[:parent_init_call.index('(')] + "(request)"
|
||||
init_fn += " %s;\n" % pcall
|
||||
init_fn += " if %s.is_none() {\n" % struct_field
|
||||
init_fn += " %s = Some(Default::default());\n" % struct_field
|
||||
init_fn += " }\n"
|
||||
init_fn += "}\n"
|
||||
|
||||
init_fn_map[init_fn_name] = init_fn
|
||||
# end handle init
|
||||
flatten_schema_fields(f, res, init_fn_map, cur, init_call)
|
||||
cur.pop()
|
||||
# endfor
|
||||
# end utility
|
||||
|
||||
schema_fields = list()
|
||||
init_fn_map = dict()
|
||||
flatten_schema_fields(request_cli_schema, schema_fields, init_fn_map)
|
||||
%>\
|
||||
let mut field_name: FieldCursor = Default::default();
|
||||
for kvarg in ${SOPT + arg_ident(KEY_VALUE_ARG)}.iter() {
|
||||
let (key, value) = parse_kv_arg(&*kvarg, err);
|
||||
if let Err(field_err) = field_name.set(&*key) {
|
||||
err.issues.push(field_err);
|
||||
}
|
||||
% for name in sorted(init_fn_map.keys()):
|
||||
${init_fn_map[name] | indent_by(4)}
|
||||
% endfor
|
||||
match &field_name.to_string()[..] {
|
||||
% for init_call, schema, fe, f in schema_fields:
|
||||
<%
|
||||
# TODO: Deduplicate !
|
||||
ptype = fe.actual_property.type
|
||||
if ptype == 'string' and 'Count' in f[-1][1]:
|
||||
ptype = 'int64'
|
||||
value_unwrap = 'value.unwrap_or("%s")' % JSON_TYPE_VALUE_MAP[ptype]
|
||||
pname = FIELD_SEP.join(mangle_subcommand(t[1]) for t in f)
|
||||
|
||||
allow_optionals = True
|
||||
opt_prefix = 'Some('
|
||||
opt_suffix = ')'
|
||||
opt_access = '.as_mut().unwrap()'
|
||||
if not allow_optionals_fn(schema):
|
||||
opt_prefix = opt_suffix = opt_access = ''
|
||||
|
||||
struct_field = 'request.' + '.'.join(t[0] for t in f)
|
||||
%>\
|
||||
"${pname}" => {
|
||||
% if init_call:
|
||||
${init_call}
|
||||
% endif
|
||||
% if fe.container_type == CTYPE_POD:
|
||||
${struct_field} = ${opt_prefix}\
|
||||
% else:
|
||||
% if opt_prefix:
|
||||
if ${struct_field}.is_none() {
|
||||
${struct_field} = Some(Default::default());
|
||||
}
|
||||
% endif
|
||||
${struct_field}${opt_access}.push(\
|
||||
% endif
|
||||
% if ptype != 'string':
|
||||
arg_from_str(${value_unwrap}, err, "${pname}", "${ptype}")\
|
||||
% else:
|
||||
${value_unwrap}.to_string()\
|
||||
% endif
|
||||
% if fe.container_type == CTYPE_POD:
|
||||
${opt_suffix}\
|
||||
% else:
|
||||
)\
|
||||
% endif
|
||||
;
|
||||
},
|
||||
% endfor # each nested field
|
||||
_ => {
|
||||
err.issues.push(CLIError::Field(FieldError::Unknown(field_name.to_string())));
|
||||
}
|
||||
}
|
||||
}
|
||||
${self._request_value_impl(c, request_cli_schema)}\
|
||||
% endif # handle struct parsing
|
||||
% if mc.media_params:
|
||||
let protocol =
|
||||
@@ -415,4 +308,110 @@ if dry_run {
|
||||
}
|
||||
}
|
||||
}\
|
||||
</%def>
|
||||
|
||||
<%def name="_request_value_impl(c, request_cli_schema)">
|
||||
<%
|
||||
allow_optionals_fn = lambda s: is_schema_with_optionals(schema_markers(s, c, transitive=False))
|
||||
|
||||
def flatten_schema_fields(schema, res, init_fn_map, cur=list(), init_call=None):
|
||||
if len(cur) == 0:
|
||||
init_call = ''
|
||||
cur = list()
|
||||
|
||||
opt_access = '.as_mut().unwrap()'
|
||||
allow_optionals = allow_optionals_fn(schema)
|
||||
parent_init_call = init_call
|
||||
if not allow_optionals:
|
||||
opt_access = ''
|
||||
for fn, f in schema.fields.iteritems():
|
||||
cur.append(['%s%s' % (mangle_ident(fn), opt_access), fn])
|
||||
if isinstance(f, SchemaEntry):
|
||||
cur[-1][0] = mangle_ident(fn)
|
||||
res.append((init_call, schema, f, list(cur)))
|
||||
else:
|
||||
if allow_optionals:
|
||||
init_fn_name = 'request_%s_init' % '_'.join(mangle_ident(t[1]) for t in cur)
|
||||
init_call = init_fn_name + '(&mut request);'
|
||||
struct_field = 'request.' + '.'.join('%s%s' % (mangle_ident(t[1]), opt_access) for t in cur[:-1])
|
||||
if len(cur) > 1:
|
||||
struct_field += '.'
|
||||
struct_field += mangle_ident(cur[-1][1])
|
||||
init_fn = "fn %s(request: &mut api::%s) {\n" % (init_fn_name, request_prop_type)
|
||||
if parent_init_call:
|
||||
pcall = parent_init_call[:parent_init_call.index('(')] + "(request)"
|
||||
init_fn += " %s;\n" % pcall
|
||||
init_fn += " if %s.is_none() {\n" % struct_field
|
||||
init_fn += " %s = Some(Default::default());\n" % struct_field
|
||||
init_fn += " }\n"
|
||||
init_fn += "}\n"
|
||||
|
||||
init_fn_map[init_fn_name] = init_fn
|
||||
# end handle init
|
||||
flatten_schema_fields(f, res, init_fn_map, cur, init_call)
|
||||
cur.pop()
|
||||
# endfor
|
||||
# end utility
|
||||
|
||||
schema_fields = list()
|
||||
init_fn_map = dict()
|
||||
flatten_schema_fields(request_cli_schema, schema_fields, init_fn_map)
|
||||
%>\
|
||||
let mut field_name = FieldCursor::default();
|
||||
for kvarg in ${SOPT + arg_ident(KEY_VALUE_ARG)}.iter() {
|
||||
let (key, value) = parse_kv_arg(&*kvarg, err);
|
||||
if let Err(field_err) = field_name.set(&*key) {
|
||||
err.issues.push(field_err);
|
||||
}
|
||||
% for name in sorted(init_fn_map.keys()):
|
||||
${init_fn_map[name] | indent_by(4)}
|
||||
% endfor
|
||||
match &field_name.to_string()[..] {
|
||||
% for init_call, schema, fe, f in schema_fields:
|
||||
<%
|
||||
ptype = actual_json_type(f[-1][1], fe.actual_property.type)
|
||||
value_unwrap = 'value.unwrap_or("%s")' % JSON_TYPE_VALUE_MAP[ptype]
|
||||
pname = FIELD_SEP.join(mangle_subcommand(t[1]) for t in f)
|
||||
|
||||
allow_optionals = True
|
||||
opt_prefix = 'Some('
|
||||
opt_suffix = ')'
|
||||
opt_access = '.as_mut().unwrap()'
|
||||
if not allow_optionals_fn(schema):
|
||||
opt_prefix = opt_suffix = opt_access = ''
|
||||
|
||||
struct_field = 'request.' + '.'.join(t[0] for t in f)
|
||||
%>\
|
||||
"${pname}" => {
|
||||
% if init_call:
|
||||
${init_call}
|
||||
% endif
|
||||
% if fe.container_type == CTYPE_POD:
|
||||
${struct_field} = ${opt_prefix}\
|
||||
% else:
|
||||
% if opt_prefix:
|
||||
if ${struct_field}.is_none() {
|
||||
${struct_field} = Some(Default::default());
|
||||
}
|
||||
% endif
|
||||
${struct_field}${opt_access}.push(\
|
||||
% endif
|
||||
% if ptype != 'string':
|
||||
arg_from_str(${value_unwrap}, err, "${pname}", "${ptype}")\
|
||||
% else:
|
||||
${value_unwrap}.to_string()\
|
||||
% endif
|
||||
% if fe.container_type == CTYPE_POD:
|
||||
${opt_suffix}\
|
||||
% else:
|
||||
)\
|
||||
% endif
|
||||
;
|
||||
},
|
||||
% endfor # each nested field
|
||||
_ => {
|
||||
err.issues.push(CLIError::Field(FieldError::Unknown(field_name.to_string())));
|
||||
}
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
Reference in New Issue
Block a user