aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jesopo2020-01-26 02:01:18 +0000
committerGravatar jesopo2020-01-26 02:01:18 +0000
commite0686ef7b4a5194789f897f9afda8b49e6f435ac (patch)
treecfea7752bd09f64492f1972f5143e841c0be0d99
parentonly show "not enough arguments" n>len(args) (diff)
signature
support command spec literals
-rw-r--r--src/utils/parse/spec.py88
1 files changed, 63 insertions, 25 deletions
diff --git a/src/utils/parse/spec.py b/src/utils/parse/spec.py
index 2cde7410..9ed5d4c5 100644
--- a/src/utils/parse/spec.py
+++ b/src/utils/parse/spec.py
@@ -60,17 +60,13 @@ SPEC_ARGUMENT_TYPES = {
}
class SpecArgument(object):
- def __init__(self, optional: bool, types: typing.List[SpecArgumentType]):
- self.optional = optional
- self.types = types
+ optional: bool = False
+ types: typing.List[SpecArgumentType] = []
-def argument_spec(spec: str) -> typing.List[SpecArgument]:
- out: typing.List[SpecArgument] = []
- for spec_argument in spec.split(" "):
- optional = spec_argument[0] == "?"
-
- argument_types: typing.List[SpecArgumentType] = []
- for argument_type in spec_argument[1:].split("|"):
+ @staticmethod
+ def parse(optional: bool, argument_types: typing.List[str]):
+ out: typing.List[SpecArgumentType] = []
+ for argument_type in argument_types:
exported = ""
if "~" in argument_type:
exported = argument_type.split("~", 1)[1]
@@ -88,26 +84,68 @@ def argument_spec(spec: str) -> typing.List[SpecArgument]:
elif exported:
argument_type_class = SpecArgumentPrivateType
- argument_types.append(argument_type_class(argument_type,
+ out.append(argument_type_class(argument_type,
argument_type_name, exported))
- out.append(SpecArgument(optional, argument_types))
- return out
-def argument_spec_human(spec: typing.List[SpecArgument],
- context: SpecArgumentContext=SpecArgumentContext.ALL) -> str:
- out: typing.List[str] = []
- for spec_argument in spec:
+ spec_argument = SpecArgument()
+ spec_argument.optional = optional
+ spec_argument.types = out
+ return spec_argument
+
+ def format(self, context: SpecArgumentContext) -> typing.Optional[str]:
+ if self.optional:
+ format = "[%s]"
+ else:
+ format = "<%s>"
+
names: typing.List[str] = []
- for argument_type in spec_argument.types:
+ for argument_type in self.types:
if not (context&argument_type.context) == 0:
name = argument_type.name() or argument_type.type
if name:
names.append(name)
-
if names:
- if spec_argument.optional:
- format = "[%s]"
- else:
- format = "<%s>"
- out.append(format % "|".join(names))
- return " ".join(out)
+ return format % "|".join(names)
+ return None
+
+class SpecArgumentTypeLiteral(SpecArgumentType):
+ def simple(self, args: typing.List[str]) -> typing.Tuple[typing.Any, int]:
+ if args and args[0] == self.name():
+ return args[0], 1
+ return None, 1
+ def error(self) -> typing.Optional[str]:
+ return None
+class SpecLiteralArgument(SpecArgument):
+ @staticmethod
+ def parse(optional: bool, literals: typing.List[str]) -> SpecArgument:
+ spec_argument = SpecLiteralArgument()
+ spec_argument.optional = optional
+ spec_argument.types = [
+ SpecArgumentTypeLiteral("literal", l, None) for l in literals]
+ return spec_argument
+
+ def format(self, context: SpecArgumentContext) -> typing.Optional[str]:
+ return "|".join(t.name() for t in self.types)
+
+def argument_spec(spec: str) -> typing.List[SpecArgument]:
+ out: typing.List[SpecArgument] = []
+ for spec_argument in spec.split(" "):
+ optional = spec_argument[0] == "?"
+
+ if spec_argument[1] == "'":
+ out.append(SpecLiteralArgument.parse(optional,
+ spec_argument[2:].split(",")))
+ else:
+ out.append(SpecArgument.parse(optional,
+ spec_argument[1:].split("|")))
+
+ return out
+
+def argument_spec_human(spec: typing.List[SpecArgument],
+ context: SpecArgumentContext=SpecArgumentContext.ALL) -> str:
+ arguments: typing.List[str] = []
+ for spec_argument in spec:
+ out = spec_argument.format(context)
+ if out:
+ arguments.append(out)
+ return " ".join(arguments)