mirror of
https://github.com/OMGeeky/google-apis-rs.git
synced 2026-02-23 15:49:49 +01:00
@@ -6,7 +6,7 @@
|
||||
<%
|
||||
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)
|
||||
hub_type_bounds, rb_type_params_s, find_fattest_resource)
|
||||
|
||||
c = new_context(schemas, resources)
|
||||
hub_type = hub_type(c.schemas, util.canonical_name())
|
||||
@@ -34,7 +34,7 @@ extern crate "yup-oauth2" as oauth2;
|
||||
extern crate mime;
|
||||
extern crate url;
|
||||
|
||||
mod cmn;
|
||||
pub mod cmn;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
@@ -45,7 +45,7 @@ use std::collections::BTreeMap;
|
||||
use std::io;
|
||||
use std::fs;
|
||||
|
||||
pub use cmn::{Hub, ReadSeek, Part, ResponseResult, RequestValue, NestedType, Delegate, DefaultDelegate};
|
||||
use cmn::{Hub, ReadSeek, Part, ResponseResult, RequestValue, NestedType, Delegate, DefaultDelegate};
|
||||
|
||||
|
||||
// ##############
|
||||
@@ -80,7 +80,7 @@ ${lib.scope_enum()}
|
||||
/// Instantiate a new hub
|
||||
///
|
||||
<%block filter="rust_doc_comment">\
|
||||
<%lib:hub_usage_example/>\
|
||||
${lib.hub_usage_example(c)}\
|
||||
</%block>
|
||||
pub struct ${hub_type}${ht_params} {
|
||||
client: RefCell<C>,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<%! from util import (activity_split, put_and, md_italic, split_camelcase_s, canonical_type_name,
|
||||
<%! from util import (activity_split, put_and, md_italic, split_camelcase_s, canonical_type_name, hub_type,
|
||||
rust_test_fn_invisible, rust_doc_test_norun, rust_doc_comment, markdown_rust_block,
|
||||
unindent_first_by, mangle_ident, mb_type, singular, scope_url_to_variant) %>\
|
||||
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) %>\
|
||||
<%namespace name="util" file="util.mako"/>\
|
||||
<%namespace name="mbuild" file="mbuild.mako"/>\
|
||||
|
||||
## If rust-doc is True, examples will be made to work for rust doc tests. Otherwise they are set
|
||||
## for github markdown.
|
||||
@@ -10,28 +13,21 @@
|
||||
<%def name="docs(c, rust_doc=True)">\
|
||||
<%
|
||||
# fr == fattest resource, the fatter, the more important, right ?
|
||||
fr = None
|
||||
if schemas:
|
||||
for candidate in sorted(schemas.values(), key=lambda s: (len(c.sta_map.get(s.id, [])), len(s.get('properties', []))), reverse=True):
|
||||
if candidate.id in c.sta_map:
|
||||
fr = candidate
|
||||
break
|
||||
# end for each candidate to check
|
||||
fr = find_fattest_resource(c)
|
||||
hub_url = 'struct.' + hub_type(c.schemas, util.canonical_name()) + '.html'
|
||||
%>\
|
||||
# Features
|
||||
|
||||
Handle the following *Resources* with ease ...
|
||||
Handle the following *Resources* with ease from the central [hub](${hub_url}) ...
|
||||
|
||||
% for r in sorted(c.rta_map.keys()):
|
||||
<%
|
||||
md_methods = list()
|
||||
doc_base_url = ''
|
||||
if not rust_doc:
|
||||
doc_base_url = cargo.doc_base_url + '/' + util.library_name() + '/'
|
||||
for method in sorted(c.rta_map[r]):
|
||||
if rust_doc:
|
||||
md_methods.append("[*%s*](struct.%s.html)" % (' '.join(n.lower() for n in reversed(method.split('.'))), mb_type(r, method)))
|
||||
else:
|
||||
# TODO: link to final destination, possibly just have one for all ...
|
||||
md_methods.append("*%s*" % method)
|
||||
|
||||
md_methods.append("[*%s*](%sstruct.%s.html)" % (' '.join(n.lower() for n in reversed(method.split('.'))), doc_base_url, mb_type(r, method)))
|
||||
md_resource = split_camelcase_s(r)
|
||||
sn = singular(canonical_type_name(r))
|
||||
|
||||
@@ -45,20 +41,24 @@ Handle the following *Resources* with ease ...
|
||||
Everything else about the *${util.canonical_name()}* API can be found at the
|
||||
[official documentation site](${documentationLink}).
|
||||
% endif
|
||||
% if rust_doc:
|
||||
|
||||
Not what you are looking for ? Find all other google APIs in their Rust [documentation index](../index.html).
|
||||
% endif
|
||||
|
||||
# Structure of this Library
|
||||
|
||||
The API is structured into the following primary items:
|
||||
|
||||
* **Hub**
|
||||
* **[Hub](${hub_url})**
|
||||
* a central object to maintain state and allow accessing all *Activities*
|
||||
* **Resources**
|
||||
* **[Resources](cmn/trait.${RESOURCE_MARKER_TRAIT}.html)**
|
||||
* primary types that you can apply *Activities* to
|
||||
* a collection of properties and *Parts*
|
||||
* **Parts**
|
||||
* **[Parts](cmn/trait.${PART_MARKER_TRAIT}.html)**
|
||||
* a collection of properties
|
||||
* never directly used in *Activities*
|
||||
* **Activities**
|
||||
* **[Activities](cmn/trait.${METHOD_BUILDER_MARKERT_TRAIT}.html)**
|
||||
* operations to apply to *Resources*
|
||||
|
||||
Generally speaking, you can invoke *Activities* like this:
|
||||
@@ -87,7 +87,7 @@ The `${api.terms.action}()` method performs the actual communication with the se
|
||||
|
||||
${'##'} Instantiating the Hub
|
||||
|
||||
${self.hub_usage_example(rust_doc)}\
|
||||
${self.hub_usage_example(c, rust_doc, fr=fr)}\
|
||||
|
||||
**TODO** Example calls - there should soon be a generator able to do that with proper inputs
|
||||
|
||||
@@ -142,21 +142,43 @@ let mut hub = ${hub_type}::new(hyper::Client::new(), auth);\
|
||||
## You will still have to set the filter for your comment type - either nothing, or rust_doc_comment !
|
||||
###############################################################################################
|
||||
###############################################################################################
|
||||
<%def name="hub_usage_example(rust_doc=True)">\
|
||||
<%def name="hub_usage_example(c, rust_doc=True, fr=None)">\
|
||||
<%
|
||||
test_filter = rust_test_fn_invisible
|
||||
main_filter = rust_doc_test_norun
|
||||
if not rust_doc:
|
||||
test_filter = lambda s: s
|
||||
test_filter = pass_through
|
||||
main_filter = markdown_rust_block
|
||||
|
||||
if fr is None:
|
||||
fr = find_fattest_resource(c)
|
||||
if fr is not None:
|
||||
fqan = None
|
||||
last_param_count = None
|
||||
for fqan in c.sta_map[fr.id]:
|
||||
_, aresource, amethod = activity_split(fqan)
|
||||
am = c.fqan_map[fqan]
|
||||
build_all_params(c, am)
|
||||
aparams, arequest_value = build_all_params(c, am)
|
||||
|
||||
if last_param_count is None or len(aparams) > last_param_count:
|
||||
m, resource, method, params, request_value = am, aresource, amethod, aparams, arequest_value
|
||||
last_param_count = len(aparams)
|
||||
# end for each fn to test
|
||||
part_prop, parts = parts_from_params(params)
|
||||
# end fill in values
|
||||
%>\
|
||||
% if fr:
|
||||
${mbuild.usage(resource, method, m, params, request_value, parts, show_all=True, rust_doc=rust_doc)}\
|
||||
% else:
|
||||
<%block filter="main_filter">\
|
||||
${util.test_prelude()}\
|
||||
|
||||
<%block filter="test_filter">\
|
||||
${self.test_hub(canonical_type_name(util.canonical_name()))}\
|
||||
${self.test_hub(hub_type(c.schemas, util.canonical_name()))}
|
||||
</%block>
|
||||
</%block>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
###############################################################################################
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
schema_to_required_property, rust_copy_value_s, is_required_property,
|
||||
hide_rust_doc_test, build_all_params, REQUEST_VALUE_PROPERTY_NAME, organize_params,
|
||||
indent_by, to_rust_type, rnd_arg_val_for_type, extract_parts, mb_type_params_s,
|
||||
hub_type_params_s, method_media_params, enclose_in, mb_type_bounds, method_response)
|
||||
hub_type_params_s, method_media_params, enclose_in, mb_type_bounds, method_response,
|
||||
METHOD_BUILDER_MARKERT_TRAIT, pass_through, markdown_rust_block, parts_from_params)
|
||||
|
||||
def get_parts(part_prop):
|
||||
if not part_prop:
|
||||
@@ -37,13 +38,9 @@
|
||||
mb_tparams = mb_type_params_s(m)
|
||||
ThisType = mb_type(resource, method) + mb_tparams
|
||||
|
||||
params, request_value = build_all_params(schemas, c, m, IO_REQUEST, REQUEST_VALUE_PROPERTY_NAME)
|
||||
part_prop = None
|
||||
for p in params:
|
||||
if p.name == 'part':
|
||||
part_prop = p
|
||||
break
|
||||
# end for each param
|
||||
params, request_value = build_all_params(c, m)
|
||||
|
||||
part_prop, parts = parts_from_params(params)
|
||||
part_desc = make_parts_desc(part_prop)
|
||||
parts = get_parts(part_prop)
|
||||
%>\
|
||||
@@ -103,11 +100,11 @@ pub struct ${ThisType}
|
||||
% endif
|
||||
}
|
||||
|
||||
impl${mb_tparams} cmn::MethodBuilder for ${ThisType} {}
|
||||
impl${mb_tparams} cmn::${METHOD_BUILDER_MARKERT_TRAIT} for ${ThisType} {}
|
||||
|
||||
impl${mb_tparams} ${ThisType} where ${', '.join(mb_type_bounds())} {
|
||||
|
||||
${self._action_fn(resource, method, m, params, request_value, parts)}\
|
||||
${self._action_fn(c, resource, method, m, params, request_value, parts)}\
|
||||
|
||||
## SETTERS ###############
|
||||
% for p in params:
|
||||
@@ -208,9 +205,11 @@ ${self._setter_fn(resource, method, m, p, part_prop, ThisType, c)}\
|
||||
|
||||
|
||||
## creates usage docs the method builder
|
||||
## show_all: If True, we will show all comments and hide no prelude. It's good to build a complete,
|
||||
## documented example for a given method.
|
||||
###############################################################################################
|
||||
###############################################################################################
|
||||
<%def name="usage(resource, method, m, params, request_value, parts)">\
|
||||
<%def name="usage(resource, method, m, params, request_value, parts=None, show_all=False, rust_doc=True)">\
|
||||
<%
|
||||
hub_type_name = hub_type(schemas, util.canonical_name())
|
||||
required_props, optional_props, part_prop = organize_params(params, request_value)
|
||||
@@ -250,24 +249,28 @@ ${self._setter_fn(resource, method, m, p, part_prop, ThisType, c)}\
|
||||
action_args = media_params and media_params[-1].type.example_value or ''
|
||||
|
||||
random_value_warning = "Values shown here are possibly random and not representative !"
|
||||
|
||||
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
|
||||
%>\
|
||||
<%block filter="rust_doc_test_norun">\
|
||||
${capture(util.test_prelude) | hide_rust_doc_test}\
|
||||
<%block filter="test_block_filter">\
|
||||
${capture(util.test_prelude) | hide_filter}\
|
||||
% if request_value:
|
||||
# use ${util.library_name()}::${request_value.id};
|
||||
% endif
|
||||
% if media_params:
|
||||
# use std::fs;
|
||||
% endif
|
||||
<%block filter="rust_test_fn_invisible">\
|
||||
${capture(lib.test_hub, hub_type_name, comments=False) | hide_rust_doc_test}
|
||||
<%block filter="test_fn_filter">\
|
||||
${capture(lib.test_hub, hub_type_name, comments=show_all) | hide_filter}
|
||||
% if request_value:
|
||||
// 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();
|
||||
% for spn, sp in request_value.get('properties', dict()).iteritems():
|
||||
% if spn not in parts:
|
||||
% if parts is not None and spn not in parts:
|
||||
<% continue %>
|
||||
% endif
|
||||
<%
|
||||
@@ -312,7 +315,7 @@ ${'.' + action_name | indent_by(13)}(${action_args});
|
||||
## create an entire 'api.terms.action' method
|
||||
###############################################################################################
|
||||
###############################################################################################
|
||||
<%def name="_action_fn(resource, method, m, params, request_value, parts)">\
|
||||
<%def name="_action_fn(c, resource, method, m, params, request_value, parts)">\
|
||||
<%
|
||||
import os.path
|
||||
join_url = lambda b, e: b.strip('/') + e
|
||||
@@ -323,7 +326,7 @@ ${'.' + action_name | indent_by(13)}(${action_args});
|
||||
qualifier = 'pub '
|
||||
add_args = ''
|
||||
rtype = 'cmn::Result<()>'
|
||||
response_schema = method_response(schemas, c, m)
|
||||
response_schema = method_response(c, m)
|
||||
|
||||
if response_schema:
|
||||
rtype = 'cmn::Result<%s>' % (response_schema.id)
|
||||
|
||||
@@ -56,7 +56,7 @@ impl${rb_params} ${ThisType} {
|
||||
|
||||
# skip part if we have a request resource. Only resources can have parts
|
||||
# that we can easily deduce
|
||||
params, request_value = build_all_params(schemas, c, m, IO_REQUEST, REQUEST_VALUE_PROPERTY_NAME)
|
||||
params, request_value = build_all_params(c, m)
|
||||
required_props, optional_props, part_prop = organize_params(params, request_value)
|
||||
|
||||
method_args = ''
|
||||
|
||||
@@ -56,6 +56,8 @@ DELEGATE_TYPE = 'Delegate'
|
||||
REQUEST_PRIORITY = 100
|
||||
REQUEST_MARKER_TRAIT = 'RequestValue'
|
||||
RESPONSE_MARKER_TRAIT = 'ResponseResult'
|
||||
RESOURCE_MARKER_TRAIT = 'Resource'
|
||||
METHOD_BUILDER_MARKERT_TRAIT = 'MethodBuilder'
|
||||
PART_MARKER_TRAIT = 'Part'
|
||||
NESTED_MARKER_TRAIT = 'NestedType'
|
||||
REQUEST_VALUE_PROPERTY_NAME = 'request'
|
||||
@@ -126,6 +128,10 @@ def hide_rust_doc_test(s):
|
||||
def unindent(s):
|
||||
return re_first_4_spaces.sub('', s)
|
||||
|
||||
# don't do anything with the passed in string
|
||||
def pass_through(s):
|
||||
return s
|
||||
|
||||
# tabs: 1 tabs is 4 spaces
|
||||
def unindent_first_by(tabs):
|
||||
def unindent_inner(s):
|
||||
@@ -377,7 +383,7 @@ 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)[1]).lower() == sid.lower():
|
||||
res.add('cmn::Resource')
|
||||
res.add('cmn::%s' % RESOURCE_MARKER_TRAIT)
|
||||
if IO_RESPONSE in iot:
|
||||
res.add(RESPONSE_MARKER_TRAIT)
|
||||
if IO_REQUEST in iot:
|
||||
@@ -444,8 +450,8 @@ def method_params(m, required=None, location=None):
|
||||
# end for each parameter
|
||||
return sorted(res, key=lambda p: (p.priority, p.name), reverse=True)
|
||||
|
||||
def _method_io(type_name, schemas, c, m, marker=None):
|
||||
s = schemas.get(m.get(type_name, dict()).get(TREF))
|
||||
def _method_io(type_name, c, m, marker=None):
|
||||
s = c.schemas.get(m.get(type_name, dict()).get(TREF))
|
||||
if s is None:
|
||||
return s
|
||||
if s and marker and marker not in schema_markers(s, c):
|
||||
@@ -454,12 +460,12 @@ def _method_io(type_name, schemas, c, m, marker=None):
|
||||
|
||||
# return the given method's request or response schema (dict), or None.
|
||||
# optionally return only schemas with the given marker trait
|
||||
def method_request(schemas, c, m, marker=None):
|
||||
return _method_io('request', schemas, c, m, marker)
|
||||
def method_request(c, m, marker=None):
|
||||
return _method_io('request', c, m, marker)
|
||||
|
||||
# As method request, but returns response instead
|
||||
def method_response(schemas, c, m, marker=None):
|
||||
return _method_io('response', schemas, c, m, marker)
|
||||
def method_response(c, m, marker=None):
|
||||
return _method_io('response', c, m, marker)
|
||||
|
||||
# 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):
|
||||
@@ -529,11 +535,11 @@ def method_media_params(m):
|
||||
|
||||
# Build all parameters used in a given method !
|
||||
# schemas, context, method(dict), 'request'|'response', request_prop_name -> (params, request_value|None)
|
||||
def build_all_params(schemas, c, m, n, npn):
|
||||
request_value = method_request(schemas, c, m)
|
||||
def build_all_params(c, m):
|
||||
request_value = method_request(c, m)
|
||||
params = method_params(m)
|
||||
if request_value:
|
||||
params.insert(0, schema_to_required_property(request_value, npn))
|
||||
params.insert(0, schema_to_required_property(request_value, REQUEST_VALUE_PROPERTY_NAME))
|
||||
# add the delegate. It's a type parameter, which has to remain in sync with the type-parameters we actually build.
|
||||
dp = type(m)({ 'name': 'delegate',
|
||||
TREF: "&'a mut %s" % DELEGATE_TYPE,
|
||||
@@ -748,6 +754,7 @@ def mb_additional_type_params(m):
|
||||
def mb_type(r, m):
|
||||
return "%s%sMethodBuilder" % (singular(canonical_type_name(r)), dot_sep_to_canonical_type_name(m))
|
||||
|
||||
# canonicalName = util.canonical_name()
|
||||
def hub_type(schemas, canonicalName):
|
||||
name = canonical_type_name(canonicalName)
|
||||
if schemas and name in schemas:
|
||||
@@ -772,6 +779,31 @@ def property(n):
|
||||
def dot_sep_to_canonical_type_name(n):
|
||||
return ''.join(canonical_type_name(singular(t)) for t in n.split('.'))
|
||||
|
||||
def find_fattest_resource(c):
|
||||
fr = None
|
||||
if c.schemas:
|
||||
for candidate in sorted(c.schemas.values(),
|
||||
key=lambda s: (len(c.sta_map.get(s.id, [])), len(s.get('properties', []))), reverse=True):
|
||||
if candidate.id in c.sta_map:
|
||||
fr = candidate
|
||||
break
|
||||
# end for each candidate to check
|
||||
# end if there are schemas
|
||||
return fr
|
||||
|
||||
# Extract valid parts from the description of the parts prop contained within the given parameter list
|
||||
# can be an empty list.
|
||||
def parts_from_params(params):
|
||||
part_prop = None
|
||||
for p in params:
|
||||
if p.name == 'part':
|
||||
part_prop = p
|
||||
break
|
||||
# end for each param
|
||||
if part_prop:
|
||||
return part_prop, extract_parts(part_prop.get('description', ''))
|
||||
return part_prop, list()
|
||||
|
||||
# Convert a scope url to a nice enum variant identifier, ready for use in code
|
||||
# name = name of the api, without version
|
||||
def scope_url_to_variant(name, url, fully_qualified=True):
|
||||
|
||||
Reference in New Issue
Block a user