fix(methods): decent solution for free methods

Now I just add a 'virtual' resource, which is called 'methods'.
The good thing about this is that it works well standalone, or
in conjunction with actual resources.

Also the system works with it just with minimal changes

Fixes #19
This commit is contained in:
Sebastian Thiel
2015-03-17 16:24:04 +01:00
parent 60d953a342
commit 79879daf1b
6 changed files with 282 additions and 179 deletions

View File

@@ -4,9 +4,9 @@
<%namespace name="mbuild" file="lib/mbuild.mako"/>\
<%namespace name="schema" file="lib/schema.mako"/>\
<%
from util import (new_context, rust_comment, rust_doc_comment,
rust_module_doc_comment, rb_type, hub_type, mangle_ident, hub_type_params_s,
hub_type_bounds, rb_type_params_s, find_fattest_resource, HUB_TYPE_PARAMETERS)
from util import (new_context, rust_comment, rust_doc_comment, rust_module_doc_comment,
rb_type, hub_type, mangle_ident, hub_type_params_s, hub_type_bounds,
rb_type_params_s, find_fattest_resource, HUB_TYPE_PARAMETERS, METHODS_RESOURCE)
c = new_context(schemas, resources, context.get('methods'))
hub_type = hub_type(c.schemas, util.canonical_name())

View File

@@ -3,7 +3,8 @@
unindent_first_by, mangle_ident, mb_type, singular, scope_url_to_variant,
PART_MARKER_TRAIT, RESOURCE_MARKER_TRAIT, METHOD_BUILDER_MARKERT_TRAIT,
find_fattest_resource, build_all_params, pass_through, parts_from_params,
REQUEST_MARKER_TRAIT, RESPONSE_MARKER_TRAIT, supports_scopes, to_api_version) %>\
REQUEST_MARKER_TRAIT, RESPONSE_MARKER_TRAIT, supports_scopes, to_api_version,
to_fqan) %>\
<%namespace name="util" file="util.mako"/>\
<%namespace name="mbuild" file="mbuild.mako"/>\
@@ -97,11 +98,7 @@ Or specifically ...
```ignore
% for an, a in c.sta_map[fr.id].iteritems():
<% category, resource, activity = activity_split(an) %>\
% if resource:
let r = hub.${mangle_ident(resource)}().${mangle_ident(activity)}(...).${api.terms.action}()
% else:
let r = hub.${mangle_ident(activity)}(...).${api.terms.action}()
% endif
% endfor
```
% endif
@@ -212,7 +209,9 @@ let mut hub = ${hub_type}::new(hyper::Client::new(), auth);\
last_param_count = None
for fqan in c.sta_map[fr.id]:
category, aresource, amethod = activity_split(fqan)
am = c.fqan_map[fqan]
# Cannot use fqan directly, as it might need remapping thanks to 'special case' resource.
# see METHODS_RESOURCE for more information
am = c.fqan_map[to_fqan(category, aresource, amethod)]
build_all_params(c, am)
aparams, arequest_value = build_all_params(c, am)

View File

@@ -90,11 +90,11 @@ impl${rb_params} ${ThisType} {
% for p in optional_props:
${property(p.name)}: Default::default(),
% endfor
% for prop_key, custom_name in api.properties.iteritems():
% for prop_key, custom_name in api.properties.iteritems():
% if prop_key == 'scopes' and (not auth or not auth.oauth2):
<% continue %>\
<% continue %>\
% endif
${custom_name}: Default::default(),
${custom_name}: Default::default(),
% endfor
}
}

View File

@@ -52,6 +52,7 @@ IO_REQUEST = 'request'
IO_TYPES = (IO_REQUEST, IO_RESPONSE)
INS_METHOD = 'insert'
DEL_METHOD = 'delete'
METHODS_RESOURCE = 'methods'
SPACES_PER_TAB = 4
@@ -416,7 +417,7 @@ def activity_split(fqan):
if not mt:
# make this the method, with not resource
mt = [t[1]]
t[1] = None
t[1] = METHODS_RESOURCE
# end
return t[0], t[1], '.'.join(mt)
@@ -593,11 +594,14 @@ def new_context(schemas, resources, methods):
continue
for mn, m in a.methods.iteritems():
assert m.id not in fqan
fqan[m.id] = m
category, resource, method = activity_split(m.id)
# Put the same method under different names to make access easier
if resource is None:
fqan[to_fqan(category, category, method)] = m
# This may be another name by which people try to find the method.
# As it has no resource, we put in a 'fake resource' (METHODS_RESOURCE), which
# needs some special treatment only in key-spots
fqan_key = m.id
if resource == METHODS_RESOURCE:
fqan_key = to_fqan(category, resource, method)
fqan[fqan_key] = m
for in_out_type_name in IO_TYPES:
t = m.get(in_out_type_name, None)
if t is None:
@@ -612,12 +616,11 @@ def new_context(schemas, resources, methods):
# delete: has no response or request
# getrating: response is a 'SomethingResult', which is still related to activities name
# the latter is used to deduce the resource name
if resource:
tn = activity_name_to_type_name(resource)
info = res.setdefault(tn, dict())
if m.id not in info:
info.setdefault(m.id, [])
# end handle other cases
tn = activity_name_to_type_name(resource)
info = res.setdefault(tn, dict())
if m.id not in info:
info.setdefault(m.id, [])
# end handle other cases
# end for each method
# end for each activity
return res, fqan
@@ -702,13 +705,9 @@ def new_context(schemas, resources, methods):
_sta_map, _fqan_map = build_activity_mappings(data_source)
for an in _fqan_map:
category, resource, activity = activity_split(an)
resource = resource or category
rta_map.setdefault(resource, list()).append(activity)
assert rtc_map.setdefault(resource, category) == category
# end for each fqan
# TODO: DEBUG: Remove this when it was run on all APIs
assert len(set(sta_map.keys()) & set(_sta_map.keys())) == 0
assert len(set(fqan_map.keys()) & set(_fqan_map.keys())) == 0, set(fqan_map.keys()) & set(_fqan_map.keys())
sta_map.update(_sta_map)
fqan_map.update(_fqan_map)
# end for each data source