| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- import math
- import typing
- import uuid
- T = typing.TypeVar("T")
- class Convertor(typing.Generic[T]):
- regex: typing.ClassVar[str] = ""
- def convert(self, value: str) -> T:
- raise NotImplementedError() # pragma: no cover
- def to_string(self, value: T) -> str:
- raise NotImplementedError() # pragma: no cover
- class StringConvertor(Convertor):
- regex = "[^/]+"
- def convert(self, value: str) -> str:
- return value
- def to_string(self, value: str) -> str:
- value = str(value)
- assert "/" not in value, "May not contain path separators"
- assert value, "Must not be empty"
- return value
- class PathConvertor(Convertor):
- regex = ".*"
- def convert(self, value: str) -> str:
- return str(value)
- def to_string(self, value: str) -> str:
- return str(value)
- class IntegerConvertor(Convertor):
- regex = "[0-9]+"
- def convert(self, value: str) -> int:
- return int(value)
- def to_string(self, value: int) -> str:
- value = int(value)
- assert value >= 0, "Negative integers are not supported"
- return str(value)
- class FloatConvertor(Convertor):
- regex = r"[0-9]+(\.[0-9]+)?"
- def convert(self, value: str) -> float:
- return float(value)
- def to_string(self, value: float) -> str:
- value = float(value)
- assert value >= 0.0, "Negative floats are not supported"
- assert not math.isnan(value), "NaN values are not supported"
- assert not math.isinf(value), "Infinite values are not supported"
- return ("%0.20f" % value).rstrip("0").rstrip(".")
- class UUIDConvertor(Convertor):
- regex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
- def convert(self, value: str) -> uuid.UUID:
- return uuid.UUID(value)
- def to_string(self, value: uuid.UUID) -> str:
- return str(value)
- CONVERTOR_TYPES = {
- "str": StringConvertor(),
- "path": PathConvertor(),
- "int": IntegerConvertor(),
- "float": FloatConvertor(),
- "uuid": UUIDConvertor(),
- }
- def register_url_convertor(key: str, convertor: Convertor) -> None:
- CONVERTOR_TYPES[key] = convertor
|