feat(lookup): LUTs and context to make better docs

Now a context is passed to utility functions, which contains the state
these may be interested in. This keeps it clean from global state.

With the lookup tables, it is possible to figure out relations between
types and document them accordingly.
This commit is contained in:
Sebastian Thiel
2015-03-03 08:06:37 +01:00
parent bb04b60dc4
commit ba98bee62f
6 changed files with 589 additions and 20 deletions

View File

@@ -3,6 +3,9 @@ The `youtube3` library allows access to all features of *YouTube*.
TODO: Library level fully fledged documentation, incuding **summary** and **usage**.
And another line, for testing
# Activities
# License
The **youtube3** library was generated by Sebastian Thiel, and is placed
under the *MIT* license.

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,10 @@
<% import util %>\
<%
import util
nested_schemas = list(util.iter_nested_types(schemas))
sta_map, fqan_map = util.build_activity_mappings(resources)
c = util.Context(sta_map, fqan_map)
%>\
<%namespace name="lib" file="lib/lib.mako"/>\
<%namespace name="mutil" file="lib/util.mako"/>\
<%namespace name="schema" file="lib/schema.mako"/>\
@@ -13,14 +19,18 @@ extern crate "yup-oauth2" as oauth2;
use std::collections::HashMap;
## SCHEMAS - normal ones
// ############
// SCHEMAS ###
// ##########
% for s in schemas.values():
${schema.new(s)}
${schema.new(s, c)}
% endfor
## SCHEMAS - nested
// ###################
// NESTED SCHEMAS ###
// #################
## some schemas are only used once and basically internal types.
## We have to find them and process them as normal types
% for s in util.iter_nested_types(schemas):
${schema.new(s)}
% for s in nested_schemas:
${schema.new(s, c)}
% endfor

View File

@@ -4,6 +4,9 @@
<%def name="docs()">\
TODO: Library level fully fledged documentation, incuding **summary** and **usage**.
And another line, for testing
# Activities
</%def>
<%def name="license()">\

View File

@@ -1,10 +1,10 @@
<%! import util %>\
## Create new schema with everything.
## 's' contains the schema structure from json to build
<%def name="new(s)">\
<%def name="new(s, c)">\
<% assert s.type == "object" %>\
<%block filter="util.rust_doc_comment">\
${doc(s)}\
${doc(s, c)}\
</%block>
#[derive(RustcEncodable, RustcDecodable, Default, Clone)]
pub struct ${s.id}\
@@ -20,6 +20,15 @@ pub struct ${s.id}\
% endif
</%def>
<%def name="doc(s)">\
${s.get('description', 'There is no detailed description.')}\
<%def name="doc(s, c)">\
${s.get('description', 'There is no detailed description.')}
% if s.id in c.sta_map:
# Activities
${''.join("* %s\n" % a for a in c.sta_map[s.id].keys())}
% else:
This schema type is not used in any activity, and only used as *part* of another schema.
% endif
</%def>

View File

@@ -1,4 +1,6 @@
import re
import collections
re_linestart = re.compile('^', flags=re.MULTILINE)
USE_FORMAT = 'use_format_field'
@@ -13,6 +15,11 @@ TYPE_MAP = {'boolean' : 'bool',
'object' : 'HashMap'}
TREF = '$ref'
# ==============================================================================
## @name Filters
# ------------------------------------------------------------------------------
## @{
# rust module doc comment filter
def rust_module_doc_comment(s):
return re_linestart.sub('//! ', s)
@@ -21,10 +28,16 @@ def rust_module_doc_comment(s):
def rust_doc_comment(s):
return re_linestart.sub('/// ', s)
# Expects v to be 'v\d+', throws otherwise
def to_api_version(v):
assert len(v) >= 2 and v[0] == 'v'
return v[1:]
# escape each string in l with "s" and return the new list
def estr(l):
return ['"%s"' % i for i in l]
## -- End Filters -- @}
# ==============================================================================
## @name Natural Language Utilities
# ------------------------------------------------------------------------------
## @{
# l must be a list, if it is more than one, 'and' will before last item
# l will also be coma-separtated
@@ -34,13 +47,14 @@ def put_and(l):
return l[0]
return ', '.join(l[:-1]) + ' and ' + l[-1]
# escape each string in l with "s" and return the new list
def estr(l):
return ['"%s"' % i for i in l]
## -- End Natural Language Utilities -- @}
# ==============================================================================
## @name Rust TypeSystem
# ------------------------------------------------------------------------------
## @{
# build a full library name (non-canonical)
def library_name(name, version):
return name + to_api_version(version)
def nested_type_name(sn, pn):
@@ -112,3 +126,50 @@ def iter_nested_types(schemas):
# end for ach property
# end for aech schma
## -- End Rust TypeSystem -- @}
# -------------------------
## @name Activity Utilities
# @{
# Returns (A, B) where
# A: { SchemaTypeName -> { fqan -> ['request'|'response', ...]}
# B: { fqan -> activity_method }
# fqan = fully qualified activity name
def build_activity_mappings(activities):
res = dict()
fqan = dict()
for an, a in activities.iteritems():
if 'methods' not in a:
continue
for mn, m in a.methods.iteritems():
assert m.id not in fqan
fqan[m.id] = m
for in_out_type_name in ('request', 'response'):
t = m.get(in_out_type_name, None)
if t is None:
continue
tn = to_rust_type(None, None, t, allow_optionals=False)
info = res.setdefault(tn, dict())
io_info = info.setdefault(m.id, [])
io_info.append(in_out_type_name)
# end for each io type
# end for each method
# end for each activity
return res, fqan
## -- End Activity Utilities -- @}
Context = collections.namedtuple('Context', ['sta_map', 'fqan_map'])
# Expects v to be 'v\d+', throws otherwise
def to_api_version(v):
assert len(v) >= 2 and v[0] == 'v'
return v[1:]
# build a full library name (non-canonical)
def library_name(name, version):
return name + to_api_version(version)