Decode TOON format string to Python data structure. Args: toon_string: TOON formatted string options: Decoding options - strict: bool (default True) - validate structure - expand_paths: 'off' (default) or 'safe' - default_delimiter: '
(toon_string: str, options: Optional[Dict[str, Any]] = None)
| 68 | |
| 69 | |
| 70 | def decode(toon_string: str, options: Optional[Dict[str, Any]] = None) -> Any: |
| 71 | """ |
| 72 | Decode TOON format string to Python data structure. |
| 73 | |
| 74 | Args: |
| 75 | toon_string: TOON formatted string |
| 76 | options: Decoding options |
| 77 | - strict: bool (default True) - validate structure |
| 78 | - expand_paths: 'off' (default) or 'safe' |
| 79 | - default_delimiter: ',' (default) |
| 80 | |
| 81 | Returns: |
| 82 | Python object (dict or list) |
| 83 | |
| 84 | Example: |
| 85 | >>> toon = '''users[1]{id,name}: |
| 86 | ... 1,Alice''' |
| 87 | >>> decode(toon) |
| 88 | {'users': [{'id': 1, 'name': 'Alice'}]} |
| 89 | """ |
| 90 | if options is None: |
| 91 | options = {} |
| 92 | |
| 93 | # Auto-detect indent size unless explicitly provided |
| 94 | indent_size = options.get('indent') |
| 95 | if indent_size is None: |
| 96 | indent_size = detect_indent(toon_string) |
| 97 | |
| 98 | opts = DecoderOptions( |
| 99 | strict=options.get('strict', DEFAULT_STRICT), |
| 100 | expand_paths=options.get('expand_paths', EXPAND_PATHS_OFF), |
| 101 | default_delimiter=options.get('default_delimiter', DEFAULT_DELIMITER) |
| 102 | ) |
| 103 | |
| 104 | lines = toon_string.split(NEWLINE) |
| 105 | |
| 106 | # Handle special case of top-level inline values |
| 107 | stripped = toon_string.strip() |
| 108 | |
| 109 | # Check if it's an empty object |
| 110 | if stripped == '{}': |
| 111 | return {} |
| 112 | |
| 113 | # Check if first line is a root-level array header (tabular or list) |
| 114 | if lines and lines[0].strip(): |
| 115 | first_line = lines[0].strip() |
| 116 | # Pattern: [N]{fields}: or [N\t]{fields}: or [N|]{fields}: or [N]: |
| 117 | array_match = re.match(r'^\[(\d+)([\t|])?\](?:\{([^}]+)\})?' + COLON + r'\s*$', first_line) |
| 118 | if array_match: |
| 119 | count = int(array_match.group(1)) |
| 120 | delimiter_indicator = array_match.group(2) |
| 121 | fields_str = array_match.group(3) |
| 122 | |
| 123 | # Determine delimiter from indicator if present |
| 124 | if delimiter_indicator == '\t': |
| 125 | detected_delimiter = TAB |
| 126 | elif delimiter_indicator == '|': |
| 127 | detected_delimiter = PIPE |
searching dependent graphs…