Last active
May 9, 2018 16:57
-
-
Save ericgj/6ef970a3504467abdea9f1e414c37dd3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env python | |
import sys | |
import re | |
from argparse import ArgumentParser | |
WORD_SPLIT = re.compile('[^a-zA-Z0-9]+') | |
FIRST_ALPHA = re.compile('^[a-zA-Z]') | |
def render(args,typename,values): | |
return u'\n'.join( | |
module_decl(typename, namespace=args.namespace) + | |
[u''] + | |
imports_decl() + | |
[u''] + | |
type_decl(typename,values) + | |
[u''] + | |
list_decl(typename,values) + | |
[u''] + | |
to_string_decl(typename,values) + | |
[u''] + | |
from_string_decl(typename,values) + | |
[u''] + | |
decode_decl(typename) + | |
[u''] + | |
encode_decl(typename) + | |
[u''] | |
) | |
def module_decl(typename,namespace=None): | |
if namespace is None: | |
return [ u'module %s exposing (..)' % (typename.as_string()) ] | |
else: | |
return [ u'module %s.%s exposing (..)' % (namespace,typename.as_string()) ] | |
def imports_decl(): | |
return ( | |
[ u'import Json.Decode as JD', | |
u'import Json.Encode as JE' | |
] | |
) | |
def type_decl(typename,values): | |
return ( | |
[ u'type %s' % (typename.as_string()) ] + | |
[ u' = %s' % (v.name()) if i == 0 else | |
u' | %s' % (v.name()) for (i,v) in enumerate(values) | |
] | |
) | |
def list_decl(typename,values): | |
return ( | |
[ u'list : List %s' % (typename.as_string()) , | |
u'list =' | |
] + | |
[ u' [ %s' % (v.name()) if i == 0 else | |
u' , %s' % (v.name()) for (i,v) in enumerate(values) | |
] + | |
[ u' ]'] | |
) | |
def to_string_decl(typename,values): | |
return ( | |
[ u'toString : %s -> String' % (typename.as_string()) , | |
u'toString %s =' % (typename.arg_name()) | |
] + | |
[ u' case %s of' % (typename.arg_name()) ] + | |
[ (u' %s ->\n' + | |
u' "%s"') % (v.name(), v.as_string()) for v in values | |
] | |
) | |
def from_string_decl(typename,values): | |
return ( | |
[ u'fromString : String -> Maybe %s' % (typename.as_string()) , | |
u'fromString s =' | |
] + | |
[ u' case s of' ] + | |
[ (u' "%s" ->\n' + | |
u' Just %s') % (v.as_string(), v.name()) for v in values | |
] + | |
[ u' _ ->', | |
u' Nothing' | |
] | |
) | |
def decode_decl(typename): | |
return ( | |
[ u'decode : JD.Decoder %s' % (typename.as_string()) , | |
u'decode =', | |
u' JD.string', | |
u' |> JD.andThen (\str ->', | |
u' fromString str', | |
u' |> Maybe.map JD.succeed', | |
u' |> Maybe.withDefault (JD.fail "Unknown %s: \' + str + \'")' % (typename.as_string(),) , | |
u' )' | |
] | |
) | |
def encode_decl(typename): | |
return ( | |
[ u'encode : %s -> JE.Value' % (typename.as_string()) , | |
u'encode value =', | |
u' JE.string <| toString value' | |
] | |
) | |
def titlecase(s): | |
if len(s) == 0: | |
return s | |
else: | |
return s[0].upper() + s[1:].lower() | |
def first_alpha_or_prefix(prefix,s): | |
if len(s) == 0: | |
return s | |
else: | |
if FIRST_ALPHA.search(s): | |
return s | |
else: | |
return prefix + s | |
class TypeName(): | |
def __init__(self,s): | |
self.value = s | |
def name(self): | |
return u''.join( | |
titlecase( first_alpha_or_prefix(u'Type',s) ) if i == 0 else titlecase(s) | |
for (i,s) in enumerate( re.split(WORD_SPLIT,self.value) ) | |
) | |
def arg_name(self): | |
return u''.join( | |
first_alpha_or_prefix(u'type',s).lower() if i == 0 else titlecase(s) | |
for (i,s) in enumerate( re.split(WORD_SPLIT,self.value) ) | |
) | |
def as_string(self): | |
return self.value | |
pgm = ArgumentParser(description=u"Generate Elm module for enum (value type)") | |
pgm.add_argument(u'tname', metavar=u'TYPE', type=TypeName, help=u'Type name') | |
pgm.add_argument(u'--namespace', metavar=u'NS', help=u'Module namespace' ) | |
args = pgm.parse_args() | |
typename = args.tname | |
values = [ TypeName(v.strip()) for v in sys.stdin.read().strip().split(u'\n') ] | |
sys.stdout.write( render(args, typename, values) ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment