|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 |
| -import re |
4 |
| -from typing import Any |
5 |
| - |
6 |
| -from reactpy_router.types import ConverterMapping, Route |
| 3 | +from reactpy_router.resolvers import StarletteResolver |
| 4 | +from reactpy_router.types import ConversionInfo, Route |
7 | 5 |
|
8 | 6 | from reactpy_django.router.converters import CONVERTERS
|
9 | 7 |
|
10 |
| -PARAM_PATTERN = re.compile(r"<(?P<type>\w+:)?(?P<name>\w+)>") |
11 |
| - |
12 | 8 |
|
13 |
| -# TODO: Make reactpy_router's SimpleResolver generic enough to where we don't have to define our own |
14 |
| -class DjangoResolver: |
| 9 | +class DjangoResolver(StarletteResolver): |
15 | 10 | """A simple route resolver that uses regex to match paths"""
|
16 | 11 |
|
17 |
| - def __init__(self, route: Route) -> None: |
18 |
| - self.element = route.element |
19 |
| - self.pattern, self.converters = parse_path(route.path) |
20 |
| - self.key = self.pattern.pattern |
21 |
| - |
22 |
| - def resolve(self, path: str) -> tuple[Any, dict[str, Any]] | None: |
23 |
| - match = self.pattern.match(path) |
24 |
| - if match: |
25 |
| - return ( |
26 |
| - self.element, |
27 |
| - {k: self.converters[k](v) for k, v in match.groupdict().items()}, |
28 |
| - ) |
29 |
| - return None |
30 |
| - |
31 |
| - |
32 |
| -# TODO: Make reactpy_router's parse_path generic enough to where we don't have to define our own |
33 |
| -def parse_path(path: str) -> tuple[re.Pattern[str], ConverterMapping]: |
34 |
| - # Convert path to regex pattern, and make sure to interpret the registered converters (ex. <int:foo>) |
35 |
| - pattern = "^" |
36 |
| - last_match_end = 0 |
37 |
| - converters: ConverterMapping = {} |
38 |
| - for match in PARAM_PATTERN.finditer(path): |
39 |
| - param_name = match.group("name") |
40 |
| - param_type = (match.group("type") or "str").strip(":") |
41 |
| - try: |
42 |
| - param_conv = CONVERTERS[param_type] |
43 |
| - except KeyError as e: |
44 |
| - raise ValueError( |
45 |
| - f"Unknown conversion type {param_type!r} in {path!r}" |
46 |
| - ) from e |
47 |
| - pattern += re.escape(path[last_match_end : match.start()]) |
48 |
| - pattern += f"(?P<{param_name}>{param_conv['regex']})" |
49 |
| - converters[param_name] = param_conv["func"] |
50 |
| - last_match_end = match.end() |
51 |
| - pattern += f"{re.escape(path[last_match_end:])}$" |
52 |
| - |
53 |
| - # Replace literal `*` with "match anything" regex pattern, if it's at the end of the path |
54 |
| - if pattern.endswith(r"\*$"): |
55 |
| - pattern = f"{pattern[:-3]}.*$" |
56 |
| - |
57 |
| - return re.compile(pattern), converters |
| 12 | + def __init__( |
| 13 | + self, |
| 14 | + route: Route, |
| 15 | + param_pattern=r"<(?P<type>\w+:)?(?P<name>\w+)>", |
| 16 | + converters: dict[str, ConversionInfo] | None = None, |
| 17 | + ) -> None: |
| 18 | + super().__init__( |
| 19 | + route=route, |
| 20 | + param_pattern=param_pattern, |
| 21 | + converters=converters or CONVERTERS, |
| 22 | + ) |
0 commit comments