feat(delegate): first attempt to get it to work

With a big but ! The most simple thing to do it was to just add
additional type parameters to the respective method.

Now the type cannot be inferred, which means type-hints must be added.
This should be easy enough, but ... has to be done somehow.
This commit is contained in:
Sebastian Thiel
2015-03-09 10:44:13 +01:00
parent ac35432b3f
commit 678b6929ca
8 changed files with 1180 additions and 479 deletions

View File

@@ -4,6 +4,9 @@ use std::marker::MarkerTrait;
use std::io::{Read, Seek};
use std::borrow::BorrowMut;
use oauth2;
use hyper;
/// Identifies the Hub. There is only one per library, this trait is supposed
/// to make intended use more explicit.
/// The hub allows to access all resource methods more easily.
@@ -43,4 +46,20 @@ impl<T: Seek + Read> ReadSeek for T {}
struct JsonServerError {
error: String,
error_description: Option<String>
}
}
/// A trait specifying functionality to help controlling any request performed by the API.
/// The trait has a conservative default implementation.
///
/// It contains methods to deal with all common issues, as well with the ones related to
/// uploading media
pub trait Delegate: Clone {
/// Called whenever there is an HttpError, usually if there are network problems.
///
/// Return retry information.
fn connection_error(&mut self, hyper::HttpError) -> oauth2::Retry {
oauth2::Retry::Abort
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
<%namespace name="schema" file="lib/schema.mako"/>\
<%
from util import (iter_nested_types, new_context, rust_comment, rust_doc_comment,
rust_module_doc_comment, rb_type, hub_type, mangle_ident, hub_type_params_s)
rust_module_doc_comment, rb_type, hub_type, mangle_ident, hub_type_params_s,
hub_type_bounds, rb_type_params_s)
nested_schemas = list(iter_nested_types(schemas))
c = new_context(resources)
@@ -36,7 +37,7 @@ use std::default::Default;
use std::io::{Read, Seek};
use std::fs;
pub use cmn::{Hub, ReadSeek, ResourceMethodsBuilder, MethodBuilder, Resource, Part, ResponseResult, RequestValue, NestedType};
pub use cmn::{Hub, ReadSeek, ResourceMethodsBuilder, MethodBuilder, Resource, Part, ResponseResult, RequestValue, NestedType, Delegate};
// ##############
@@ -80,9 +81,7 @@ pub struct ${hub_type}${ht_params} {
impl<'a, C, NC, A> Hub for ${hub_type}${ht_params} {}
impl<'a, C, NC, A> ${hub_type}${ht_params}
where NC: hyper::net::NetworkConnector,
C: BorrowMut<hyper::Client<NC>> + 'a,
A: oauth2::GetToken {
where ${', '.join(hub_type_bounds())} {
pub fn new(client: C, authenticator: A) -> ${hub_type}${ht_params} {
${hub_type} {
@@ -93,7 +92,7 @@ impl<'a, C, NC, A> ${hub_type}${ht_params}
}
% for resource in sorted(c.rta_map.keys()):
pub fn ${mangle_ident(resource)}(&'a self) -> ${rb_type(resource)}<'a, C, NC, A> {
pub fn ${mangle_ident(resource)}(&'a self) -> ${rb_type(resource)}${rb_type_params_s(resource, c)} {
${rb_type(resource)} { hub: &self }
}
% endfor

View File

@@ -30,7 +30,7 @@ Handle the following *Resources* with ease ...
md_resource = split_camelcase_s(r)
sn = singular(canonical_type_name(r))
if rust_ddoc and sn in schemas:
if rust_doc and sn in schemas:
md_resource = '[%s](struct.%s.html)' % (md_resource, singular(canonical_type_name(r)))
%>\
* ${md_resource} (${put_and(md_methods)})

View File

@@ -6,7 +6,7 @@
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)
hub_type_params_s, method_media_params, enclose_in, mb_type_bounds)
def get_parts(part_prop):
if not part_prop:
@@ -101,7 +101,7 @@ pub struct ${ThisType}
impl${mb_tparams} MethodBuilder for ${ThisType} {}
impl${mb_tparams} ${ThisType} {
impl${mb_tparams} ${ThisType} where ${', '.join(mb_type_bounds())} {
${self._action_fn(resource, method, m, params, request_value, parts)}\

View File

@@ -4,7 +4,7 @@
to_fqan, indent_all_but_first_by, schema_markers,
activity_input_type, TREF, method_io, IO_REQUEST, schema_to_required_property,
rust_copy_value_s, is_required_property, organize_params, REQUEST_VALUE_PROPERTY_NAME,
build_all_params, rb_type_params_s, hub_type_params_s, mb_type_params_s)
build_all_params, rb_type_params_s, hub_type_params_s, mb_type_params_s, mb_additional_type_params)
%>\
<%namespace name="util" file="util.mako"/>\
<%namespace name="lib" file="lib.mako"/>\
@@ -15,7 +15,7 @@
<%def name="new(resource, c)">\
<%
hub_type_name = hub_type(util.canonical_name())
rb_params = rb_type_params_s()
rb_params = rb_type_params_s(resource, c)
ThisType = rb_type(resource) + rb_params
%>\
/// A builder providing access to all methods supported on *${singular(resource)}* resources.
@@ -42,7 +42,7 @@ pub struct ${ThisType}
C: 'a,
A: 'a, {
hub: &'a ${hub_type_name}${hub_type_params_s()}
hub: &'a ${hub_type_name}${hub_type_params_s()},
}
impl${rb_params} ResourceMethodsBuilder for ${ThisType} {}
@@ -71,7 +71,7 @@ impl${rb_params} ${ThisType} {
///
${m.description | rust_doc_comment, indent_all_but_first_by(1)}
% endif
pub fn ${mangle_ident(a)}(&self${method_args}) -> ${RType}${mb_tparams} {
pub fn ${mangle_ident(a)}<${', '.join(mb_additional_type_params(m))}>(&self${method_args}) -> ${RType}${mb_tparams} {
${RType} {
hub: self.hub,
% for p in required_props:

View File

@@ -47,6 +47,7 @@ REQUEST_MARKER_TRAIT = 'RequestValue'
PART_MARKER_TRAIT = 'Part'
NESTED_MARKER_TRAIT = 'NestedType'
REQUEST_VALUE_PROPERTY_NAME = 'request'
DELEGATE_TYPE_PARAM = 'D'
PROTOCOL_TYPE_INFO = {
'simple' : {
@@ -487,12 +488,23 @@ def method_media_params(m):
return res
# 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_io(schemas, c, m, n)
params = method_params(m)
if request_value:
params.insert(0, schema_to_required_property(request_value, npn))
# 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: DELEGATE_TYPE_PARAM,
'priority': 0,
'description':
"""The delegate implementation is consulted whenever there is an intermediate result, or if something goes wrong
while executing the actual API request.
It should be used to handle progress information, and to implement a certain level of resilience."""})
params.append(dp)
return params, request_value
@@ -568,13 +580,32 @@ def _to_type_params_s(p):
def hub_type_params_s():
return _to_type_params_s(HUB_TYPE_PARAMETERS)
# return a list of where statements to server as bounds for the hub.
def hub_type_bounds():
return ['NC: hyper::net::NetworkConnector',
"C: BorrowMut<hyper::Client<NC>> + 'a",
'A: oauth2::GetToken']
# return list of type bounds required by method builder
def mb_type_bounds():
return hub_type_bounds() + [DELEGATE_TYPE_PARAM + ': Delegate']
DEFAULT_MB_TYPE_PARAMS = (DELEGATE_TYPE_PARAM, )
_rb_type_params = ("'a", ) + HUB_TYPE_PARAMETERS
# type parameters for a resource builder - keeps hub as borrow
def rb_type_params_s():
return _to_type_params_s(("'a", ) + HUB_TYPE_PARAMETERS)
def rb_type_params_s(resource, c):
return _to_type_params_s(_rb_type_params)
# type params for the given method builder, as string suitable for Rust code
def mb_type_params_s(m):
return _to_type_params_s(("'a", ) + HUB_TYPE_PARAMETERS)
return _to_type_params_s(_rb_type_params + DEFAULT_MB_TYPE_PARAMS)
# as rb_additional_type_params, but for an individual method, as seen from a resource builder !
def mb_additional_type_params(m):
return DEFAULT_MB_TYPE_PARAMS
# return type name for a method on the given resource
def mb_type(r, m):

View File

@@ -2,6 +2,9 @@ use std::marker::MarkerTrait;
use std::io::{Read, Seek};
use std::borrow::BorrowMut;
use oauth2;
use hyper;
/// Identifies the Hub. There is only one per library, this trait is supposed
/// to make intended use more explicit.
/// The hub allows to access all resource methods more easily.
@@ -41,4 +44,20 @@ impl<T: Seek + Read> ReadSeek for T {}
struct JsonServerError {
error: String,
error_description: Option<String>
}
}
/// A trait specifying functionality to help controlling any request performed by the API.
/// The trait has a conservative default implementation.
///
/// It contains methods to deal with all common issues, as well with the ones related to
/// uploading media
pub trait Delegate: Clone {
/// Called whenever there is an HttpError, usually if there are network problems.
///
/// Return retry information.
fn connection_error(&mut self, hyper::HttpError) -> oauth2::Retry {
oauth2::Retry::Abort
}
}