|
5 | 5 | from typing import Set |
6 | 6 |
|
7 | 7 | from c8y_api.model._base import ComplexObject |
| 8 | +from c8y_api.model._util import _StringUtil |
8 | 9 |
|
9 | 10 |
|
| 11 | +def as_tuples(json_data, *path: str | tuple): |
| 12 | + """Parse a JSON structure as tuples from paths. |
| 13 | +
|
| 14 | + Args: |
| 15 | + json_data (dict): A JSON structure as Python dict |
| 16 | + path (*str|tuple): Path(s) to extract from |
| 17 | + the structure; Use dots to separate JSON levels; Arrays are not |
| 18 | + supported. |
| 19 | +
|
| 20 | + Mote: This function automatically converts path segments from |
| 21 | + Python snake_case to pascalCase, e.g. `creation_time` will match |
| 22 | + both `creation_time` and `creationTime` fields. |
| 23 | +
|
| 24 | + Returns: |
| 25 | + A tuple with `len(path)` elements containing the values as-is defined |
| 26 | + in the JSON structure; an invalid path will result in None. |
| 27 | + """ |
| 28 | + def resolve(segments, default=None): |
| 29 | + json_level = json_data |
| 30 | + for segment in segments[:-1]: |
| 31 | + if segment in json_level: |
| 32 | + json_level = json_level[segment] |
| 33 | + continue |
| 34 | + pascal_segment = _StringUtil.to_pascal_case(segment) |
| 35 | + if pascal_segment in json_level: |
| 36 | + json_level = json_level[pascal_segment] |
| 37 | + continue |
| 38 | + return default |
| 39 | + return json_level.get(segments[-1], json_level.get(_StringUtil.to_pascal_case(segments[-1]), default)) |
| 40 | + |
| 41 | + # each p in path(s) can be a string or a tuple |
| 42 | + return tuple(resolve(p[0].split('.'), p[1]) if isinstance(p, tuple) else resolve(p.split('.')) for p in path ) |
| 43 | + |
10 | 44 | class SimpleObjectParser(object): |
11 | 45 | """A parser for simple (without fragments) Cumulocity database objects. |
12 | 46 |
|
|
0 commit comments