Files
Buffteks-Website/streamlit-venv/lib/python3.10/site-packages/streamlit_antd_components/utils/parser.py
2025-01-10 21:40:35 +00:00

151 lines
4.5 KiB
Python
Executable File

#!/usr/bin/env python
# _*_coding:utf-8_*_
"""
@Time : 2023/6/6 10:13
@Author : ji hao ran
@File : parser.py
@Project : StreamlitAntdComponents
@Software : PyCharm
"""
from .data_class import BsIcon, AntIcon, Tag
from dataclasses import is_dataclass
from typing import List, Union, Callable, Any
__all__ = ['update_kw', 'update_index', 'get_default', 'ParseItems', 'parse_icon']
def parse_icon(icon):
if isinstance(icon, str):
icon = BsIcon(name=icon).__dict__
elif isinstance(icon, BsIcon):
icon = icon.__dict__
elif isinstance(icon, AntIcon):
icon = icon.__dict__
return icon
def parse_tag(tag):
if isinstance(tag, Tag):
tag = tag.__dict__
elif isinstance(tag, str):
tag = Tag(tag).__dict__
elif isinstance(tag, list):
tag = [Tag(i).__dict__ if isinstance(i, str) else i.__dict__ for i in tag]
return tag
def update_kw(kw: dict, **kwargs):
r = kw.copy()
r.update(**kwargs)
delete_keys = ['format_func', 'key', 'on_change', 'args', 'kwargs']
for k in delete_keys:
if k in r.keys():
del r[k]
return r
def update_index(i, return_type='array'):
if return_type == 'array':
if isinstance(i, int):
return [i]
if i is None:
return []
return i
def get_default(index, return_index, kv):
if return_index:
return index
else:
if isinstance(index, int):
return kv.get(index)
if isinstance(index, list):
return [kv.get(i) for i in index]
if index is None:
return None
class ParseItems:
def __init__(self, items: List[Union[str, dict, Any]], format_func: Union[str, Callable] = None):
"""
:param items: component items data
:param format_func: format component item label func
"""
self.items = items if items is not None else []
self.format_func = format_func
def _label_format(self, label: str):
if self.format_func is not None:
if self.format_func == 'title':
return str.title(label)
elif self.format_func == 'upper':
return str.upper(label)
elif isinstance(self.format_func, Callable):
return self.format_func(label)
else:
return label
def transfer(self):
r, kv = [], {}
for idx, v in enumerate(self.items):
item = {'title': v}
item.update(key=idx) # add key
item.update(titleFormatter=self._label_format(v))
r.append(item)
kv.update({idx: v})
return r, kv
@staticmethod
def _item_to_dict(item, field: str = 'label'):
if isinstance(item, str):
it = {field: item}
elif is_dataclass(item):
it = item.__dict__
elif isinstance(item, dict):
it = item.copy()
else:
it = {}
if it.get('icon'):
it['icon'] = parse_icon(it.get('icon'))
if it.get('tag'):
it['tag'] = parse_tag(it.get('tag'))
return it
def single(self, key_field: str = 'key', label_field: str = 'label', key_as_str: bool = False):
"""parse single level component items data"""
r, kv = [], {}
for idx, v in enumerate(self.items):
item = self._item_to_dict(v, label_field)
label = item.get(label_field)
item.update({key_field: str(idx) if key_as_str else idx}) # add key
item.update({label_field: self._label_format(label)})
r.append(item)
kv.update({idx: label})
return r, kv
def multi(self, field: str = 'key'):
"""parse multiple levels component items data"""
key, kv0 = 0, []
def _add_key(items):
r1 = []
nonlocal key
for i in items:
item = self._item_to_dict(i)
kv0.append(item.get('label'))
children = item.get('children')
item.update({field: key}) # add field
key += 1
item.update(label=self._label_format(item.get('label')))
if children:
item.update(children=_add_key(children))
r1.append(item)
return r1
r = _add_key(self.items)
kv = {idx: v for idx, v in enumerate(kv0)}
return r, kv