Skip to content

Instantly share code, notes, and snippets.

@djungelorm
Created June 7, 2016 02:50
Show Gist options
  • Save djungelorm/e6a5c2e73393779f41371a2febe88854 to your computer and use it in GitHub Desktop.
Save djungelorm/e6a5c2e73393779f41371a2febe88854 to your computer and use it in GitHub Desktop.
krpc-clientgen examples
import os
from krpctools.clientgen.generator import Generator
from krpctools.clientgen.docparser import DocParser
class ExampleGenerator(Generator):
def __init__(self, macro_template, service, definition_files):
super(ExampleGenerator, self).__init__(macro_template, service, definition_files)
@classmethod
def parse_name(cls, name):
""" Return the name of a procedure/method/property identifier. Name is passed to this method in CamelCase. """
return name
def parse_type(self, typ):
""" Return the string representation of a type """
return typ.protobuf_type
def parse_return_type(self, typ):
""" Return the string representation of a return type """
if typ is None:
return 'void'
return self.parse_type(typ)
def parse_parameter_type(self, typ):
""" Return the string representation of a parameter type """
return self.parse_type(typ)
def parse_default_value(self, value, typ):
""" Given a value and it's type, return a string representing the default value """
return str(value)
@staticmethod
def parse_documentation(documentation):
""" Given a C# doc string, produce the doc string for your language.
Use a DocParser to implement this if needed. """
return documentation
@staticmethod
def parse_context(context):
""" Update the context dictionary to add extra information to the dict passed to the template """
return context
# Set the generator and template path so that the krpc-clientgen script can find them
generator = ExampleGenerator
tmpl = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'example.tmpl')
Service {{ service_name }}
{% for name,info in procedures.items() %}
Procedure {{ name }}
Return type {{ info.return_type }}
{% endfor %}
{% for name,info in properties.items() %}
Property {{ name }}
Type {{ info.type }}
{% endfor %}
{% for name,info in classes.items() %}
Class {{ name }}
{% for method_name,method_info in info.methods.items() %}
Method {{ method_name }}
Return type {{ method_info.return_type }}
{% endfor %}
{% for static_method_name,static_method_info in info.static_methods.items() %}
Static_Method {{ static_method_name }}
Return type {{ static_method_info.return_type }}
{% endfor %}
{% for property_name,property_info in info.properties.items() %}
Property {{ property_name }}
Type {{ property_info.type }}
{% endfor %}
{% endfor %}
import os
import krpc.types
from krpctools.clientgen.generator import Generator
from krpctools.clientgen.docparser import DocParser
from krpctools.utils import lower_camel_case
class HaskellGenerator(Generator):
def __init__(self, macro_template, service, definition_files):
super(HaskellGenerator, self).__init__(macro_template, service, definition_files)
@classmethod
def parse_name(cls, name):
""" Return the name of an identifier. Name is passed to this method in CamelCase. """
# Note: template uses filters to alter the casing of names
return name
def parse_type(self, typ):
""" Return the string representation of a type """
if isinstance(typ, krpc.types.ValueType):
typ = typ.protobuf_type
if typ == 'string':
return 'Text'
elif typ == 'bytes':
return '????' #TODO
elif typ == 'float':
return 'Float'
elif typ == 'double':
return 'Double'
elif typ == 'bool':
return 'Bool'
elif 'int' in typ:
int_type_map = {
'int16' : 'Int16',
'uint16': 'UInt16',
'int32' : 'Int32',
'uint32': 'UInt32',
'int64' : 'Int64',
'uint64': 'UInt64'
}
return int_type_map[typ]
#TODO: finish implementing
return typ.protobuf_type
def parse_return_type(self, typ):
""" Return the string representation of a return type """
if typ is None:
return 'Bool' # void functions return Bool?
return self.parse_type(typ)
def parse_parameter_type(self, typ):
""" Return the string representation of a parameter type """
return self.parse_type(typ)
def parse_default_value(self, value, typ):
""" Given a value and it's type, return a string representing the default value """
# TODO: return the correct Haskell value expression
return str(value)
@staticmethod
def parse_documentation(documentation):
""" Given a C# doc string, produce the doc string for your language.
Use a DocParser to implement this if needed. """
#TODO: add documentation to generated code
return None
@staticmethod
def parse_context(context):
""" Update the context dictionary to add extra information to the dict passed to the template """
return context
# Set the generator and template path so that the krpc-clientgen script can find them
generator = HaskellGenerator
tmpl = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'haskell.tmpl')
{-# LANGUAGE RecordWildCards #-}
module KRPCHS.{{ service_name }}
(
{% for name in classes.keys() + enumerations.keys() %}
, {{ name }}(..)
{% endfor %}
{% for name in procedures.keys() %}
, {{ name | lower_camel_case }}
{% endfor %}
{% for name,info in properties.items() %}
{% if info.getter %}
, get{{ name }}
{% endif %}
{% if info.setter %}
, set{{ name }}
{% endif %}
{% endfor %}
{% for clsname,clsinfo in classes.items() %}
{% for name in clsinfo.methods.keys() %}
, {{ clsname | lower_camel_case }}{{ name }}
{% endfor %}
{% for name in clsinfo.static_methods.keys() %}
, {{ clsname | lower_camel_case }}{{ name }}
{% endfor %}
{% for name,info in clsinfo.properties.items() %}
{% if info.getter %}
, get{{ clsname }}{{ name }}
{% endif %}
{% if info.setter %}
, set{{ clsname }}{{ name }}
{% endif %}
{% endfor %}
{% endfor %}
) where
import Data.Map
import Data.Int
import Data.Word
import Data.Text
import KRPCHS.Internal.Requests
import KRPCHS.Internal.SerializeUtils
{% for name in classes.keys() %}
newtype {{ name }} = {{ name }} { {{ name | lower_camel_case }}Id :: Int }
deriving (Show, Eq, Ord)
instance PbSerializable {{ name }} where
encodePb = encodePb . {{ name | lower_camel_case }}Id
decodePb b = {{ name }} <$> decodePb b
{% endfor %}
{% for name,info in enumerations.items() %}
data {{ name }}
= {% for value in info['values'] %}
{% if not loop.first %} | {% endif %}{{ name }}'{{ value.name }}
{% endfor %}
deriving (Show, Eq, Ord, Enum)
instance PbSerializable {{ name }} where
encodePb = encodePb . fromEnum
decodePb b = toEnum <$> decodePb b
{% endfor %}
{% macro parameter_types(parameters) %}
{% for p in parameters %}{{ p.type }} -> {% endfor %}
{% endmacro %}
{% macro parameter_names(parameters) %}
{% for p in parameters %}{{ p.name | lower_camel_case }}Arg {% endfor %}
{% endmacro %}
{% macro make_arguments(parameters) %}
{% for p in parameters %}makeArgument {{ loop.index0 }} {{ p.name | lower_camel_case }}Arg{% if not loop.last%}, {% endif %}{% endfor %}
{% endmacro %}
{% for name,info in procedures.items() %}
{{ name | lower_camel_case }} :: {{ parameter_types(info.parameters) }}RPCContext ({{ info.return_type }})
{{ name | lower_camel_case }} {{ parameter_names(info.parameters) }}= do
let r = makeRequest "{{ service_name }}" "{{ name }}" [ {{ make_arguments(info.parameters) }}]
res <- sendRequest r
TODO: process result
{% endfor %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment