| 21 | |
| 22 | |
| 23 | class Querystring: |
| 24 | array_format: ArrayFormat |
| 25 | nested_format: NestedFormat |
| 26 | |
| 27 | def __init__( |
| 28 | self, |
| 29 | *, |
| 30 | array_format: ArrayFormat = "repeat", |
| 31 | nested_format: NestedFormat = "brackets", |
| 32 | ) -> None: |
| 33 | self.array_format = array_format |
| 34 | self.nested_format = nested_format |
| 35 | |
| 36 | def parse(self, query: str) -> Mapping[str, object]: |
| 37 | # Note: custom format syntax is not supported yet |
| 38 | return parse_qs(query) |
| 39 | |
| 40 | def stringify( |
| 41 | self, |
| 42 | params: Params, |
| 43 | *, |
| 44 | array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN, |
| 45 | nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN, |
| 46 | ) -> str: |
| 47 | return urlencode( |
| 48 | self.stringify_items( |
| 49 | params, |
| 50 | array_format=array_format, |
| 51 | nested_format=nested_format, |
| 52 | ) |
| 53 | ) |
| 54 | |
| 55 | def stringify_items( |
| 56 | self, |
| 57 | params: Params, |
| 58 | *, |
| 59 | array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN, |
| 60 | nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN, |
| 61 | ) -> list[tuple[str, str]]: |
| 62 | opts = Options( |
| 63 | qs=self, |
| 64 | array_format=array_format, |
| 65 | nested_format=nested_format, |
| 66 | ) |
| 67 | return flatten([self._stringify_item(key, value, opts) for key, value in params.items()]) |
| 68 | |
| 69 | def _stringify_item( |
| 70 | self, |
| 71 | key: str, |
| 72 | value: Data, |
| 73 | opts: Options, |
| 74 | ) -> list[tuple[str, str]]: |
| 75 | if isinstance(value, Mapping): |
| 76 | items: list[tuple[str, str]] = [] |
| 77 | nested_format = opts.nested_format |
| 78 | for subkey, subvalue in value.items(): |
| 79 | items.extend( |
| 80 | self._stringify_item( |
no outgoing calls