def parse_struct_res()

in src/models/struxgpt_v1.py [0:0]


    def parse_struct_res(self, **kwargs) -> Tuple[bool, str]:
        if is_empty(self.raw_query):
            return False, 'input_error'
           
        error_type = None
        try:  # check format
            error_type = 'result_spliter'
            scope, hierarchy = self.raw_response.split('```')[-4::2]
            self.scope = white_space_fix(scope)
            assert self.scope, 'result_scope_str'
        except:
            return False, error_type

        def _parse_line(line: str):
            # hierarchy_idx = len(line.split('    ')) - 1
            hierarchy_idx = [c != ' ' for c in line].index(True) // 4
            assert hierarchy_idx < 2, 'result_level_overflow'
            noindent_line = white_space_fix(line)
            indicator, *content = noindent_line.split()
            content = ' '.join(content)
            assert indicator.count('.') == hierarchy_idx + 1, 'result_hierarchy_format'
            assert indicator.endswith('.') and all(int(flag) > 0 for flag in indicator.split('.')[:-1]), 'result_indicator_format'
            return hierarchy_idx, indicator, content
        
        def _add_aspect(name: str, descs: List[str]):
            aspect_item = AspectItem(name=name)
            aspect_item.set_descs(deepcopy(descs))
            self.aspects.append(aspect_item)
        
        try:  # check content
            error_type = 'result_aspect'
            res_lines = hierarchy.strip().splitlines()

            prev_aspect_idx = -1
            prev_aspect_name, prev_aspect_descs = '', []
            for li, line in enumerate(res_lines):
                hierarchy_idx, indicator, content = _parse_line(line)
                indicators = indicator.split('.')[:-1]
                if hierarchy_idx == 0:
                    aspect_idx = int(indicators[0])
                    assert aspect_idx != prev_aspect_idx and aspect_idx >= 1
                    if prev_aspect_idx != -1:
                        assert prev_aspect_name and len(prev_aspect_descs), 'parse_error'
                        _add_aspect(prev_aspect_name, prev_aspect_descs)
                    prev_aspect_idx, prev_aspect_name, prev_aspect_descs = \
                        aspect_idx, content, []
                else:
                    aspect_idx, desc_idx = list(map(int, indicators))
                    assert aspect_idx == prev_aspect_idx
                    assert desc_idx == len(prev_aspect_descs) + 1
                    prev_aspect_descs.append(content)

            assert prev_aspect_name and len(prev_aspect_descs)
            _add_aspect(prev_aspect_name, prev_aspect_descs)

        except AssertionError as e:
            return False, str(e)

        except:
            return False, 'Unknown Error'
        
        return True, self.to_json()