Add typing in HLDS code, change price to int
This commit is contained in:
parent
798e08d74b
commit
fe593fece6
4 changed files with 42 additions and 31 deletions
|
@ -1,7 +1,9 @@
|
|||
# Import this class to load the standard HLDS definitions
|
||||
|
||||
from os import path
|
||||
from typing import List
|
||||
from .parser import parse_all_directory
|
||||
from .models import Location
|
||||
|
||||
|
||||
__all__ = ["location_definitions"]
|
||||
|
@ -10,4 +12,4 @@ __all__ = ["location_definitions"]
|
|||
DATA_DIR = path.join(path.dirname(__file__), "..", "..", "data")
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
location_definitions = parse_all_directory(DATA_DIR)
|
||||
location_definitions: List[Location] = parse_all_directory(DATA_DIR)
|
||||
|
|
|
@ -80,7 +80,7 @@ identifier = /[a-z0-9_-]+/ ;
|
|||
string = /[^\n]+/ ;
|
||||
choice_type = 'single_choice' | 'multi_choice' ;
|
||||
|
||||
number = /[0-9]+(\.[0-9]+)?/ ;
|
||||
int = /[0-9]+/ ;
|
||||
|
||||
currency = '€' ;
|
||||
price = currency:currency s value:number ;
|
||||
price = currency:currency s value_unit:int [ '.' value_cents:/[0-9]{,2}/ ] ;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
from typing import List
|
||||
from typing import List, Mapping, Any
|
||||
|
||||
|
||||
def _format_tags(tags):
|
||||
|
@ -19,11 +19,11 @@ def _format_type_and_choice(type_and_choice):
|
|||
|
||||
class Option:
|
||||
def __init__(self, id_, *, name, description, price, tags):
|
||||
self.id = id_
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.price = price
|
||||
self.tags = tags
|
||||
self.id: str = id_
|
||||
self.name: str = name
|
||||
self.description: str = description
|
||||
self.price: int = price
|
||||
self.tags: List[str] = tags
|
||||
|
||||
def __str__(self):
|
||||
return "{0.id}: {0.name}{1}{2}{3}".format(
|
||||
|
@ -36,9 +36,9 @@ class Option:
|
|||
|
||||
class Choice:
|
||||
def __init__(self, id_, *, name, description, options):
|
||||
self.id = id_
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.id: str = id_
|
||||
self.name: str = name
|
||||
self.description: str = description
|
||||
|
||||
self.options: List[Option] = options
|
||||
|
||||
|
@ -52,11 +52,11 @@ class Choice:
|
|||
|
||||
class Dish:
|
||||
def __init__(self, id_, *, name, description, price, tags, choices):
|
||||
self.id = id_
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.price = price
|
||||
self.tags = tags
|
||||
self.id: str = id_
|
||||
self.name: str = name
|
||||
self.description: str = description
|
||||
self.price: int = price
|
||||
self.tags: List[str] = tags
|
||||
|
||||
self.choices: List[(str, Choice)] = choices
|
||||
|
||||
|
@ -72,9 +72,9 @@ class Dish:
|
|||
|
||||
class Location:
|
||||
def __init__(self, id_, *, name, attributes, dishes):
|
||||
self.id = id_
|
||||
self.name = name
|
||||
self.attributes = attributes
|
||||
self.id: str = id_
|
||||
self.name: str = name
|
||||
self.attributes: Mapping[str, Any] = attributes
|
||||
|
||||
self.dishes: List[Dish] = dishes
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
from glob import glob
|
||||
from os import path
|
||||
import itertools
|
||||
from typing import Iterable, List, Union, Tuple
|
||||
from tatsu import parse as tatsu_parse
|
||||
from tatsu.ast import AST
|
||||
from .models import Location, Choice, Option, Dish
|
||||
|
||||
|
||||
|
@ -18,7 +20,7 @@ def filter_instance(cls, iterable):
|
|||
|
||||
# pylint: disable=no-self-use
|
||||
class HldsSemanticActions:
|
||||
def location(self, ast):
|
||||
def location(self, ast) -> Location:
|
||||
choices = {choice.id: choice for choice in filter_instance(Choice, ast["items_"])}
|
||||
dishes = filter_instance(Dish, ast["items_"])
|
||||
for dish in dishes:
|
||||
|
@ -33,7 +35,7 @@ class HldsSemanticActions:
|
|||
dishes=dishes,
|
||||
)
|
||||
|
||||
def base_block(self, ast):
|
||||
def base_block(self, ast) -> Dish:
|
||||
return Dish(
|
||||
ast["id"],
|
||||
name=ast["name"],
|
||||
|
@ -43,7 +45,7 @@ class HldsSemanticActions:
|
|||
choices=ast["choices"],
|
||||
)
|
||||
|
||||
def choice_block(self, ast):
|
||||
def choice_block(self, ast) -> Choice:
|
||||
return Choice(
|
||||
ast["id"],
|
||||
name=ast["name"],
|
||||
|
@ -51,14 +53,14 @@ class HldsSemanticActions:
|
|||
options=ast["entries"],
|
||||
)
|
||||
|
||||
def indent_choice_block(self, ast):
|
||||
def indent_choice_block(self, ast) -> Tuple[str, Union[Choice, AST]]:
|
||||
return (
|
||||
(ast["type"], self.choice_block(ast))
|
||||
if ast["kind"] == "declaration" else
|
||||
(ast["type"], ast["id"])
|
||||
)
|
||||
|
||||
def indent_choice_entry(self, ast):
|
||||
def indent_choice_entry(self, ast) -> Option:
|
||||
return Option(
|
||||
ast["id"],
|
||||
name=ast["name"],
|
||||
|
@ -69,8 +71,15 @@ class HldsSemanticActions:
|
|||
|
||||
noindent_choice_entry = indent_choice_entry
|
||||
|
||||
def price(self, ast):
|
||||
return "{0[currency]} {0[value]}".format(ast)
|
||||
def price(self, ast) -> int:
|
||||
return (
|
||||
100 * int(ast["value_unit"]) +
|
||||
(
|
||||
0 if not ast["value_cents"] else
|
||||
10 * int(ast["value_cents"]) if len(ast["value_cents"]) == 1 else
|
||||
int(ast["value_cents"])
|
||||
)
|
||||
)
|
||||
|
||||
def _default(self, ast):
|
||||
return ast
|
||||
|
@ -78,22 +87,22 @@ class HldsSemanticActions:
|
|||
SEMANTICS = HldsSemanticActions()
|
||||
|
||||
|
||||
def parse(menu):
|
||||
def parse(menu: str) -> List[Location]:
|
||||
parsed = tatsu_parse(GRAMMAR, menu, semantics=SEMANTICS)
|
||||
return parsed
|
||||
|
||||
|
||||
def parse_file(filename):
|
||||
def parse_file(filename: str) -> List[Location]:
|
||||
with open(filename, "r") as file_handle:
|
||||
return parse(file_handle.read())
|
||||
|
||||
|
||||
def parse_files(files):
|
||||
def parse_files(files: Iterable[str]) -> List[Location]:
|
||||
menus = map(parse_file, files)
|
||||
return list(itertools.chain.from_iterable(menus))
|
||||
|
||||
|
||||
def parse_all_directory(directory):
|
||||
def parse_all_directory(directory: str) -> List[Location]:
|
||||
# TODO Use proper way to get resources, see https://stackoverflow.com/a/10935674
|
||||
files = glob(path.join(directory, "**.hlds"), recursive=True)
|
||||
return parse_files(files)
|
||||
|
|
Loading…
Reference in a new issue