import re
from typing import Dict, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from type_mapping import MatterType
from models.enums import MatterEnum
def _build_numeric_or_id_types():
from .type_mapping import MatterType
numeric_types = set()
excluded = {'bool', 'string', 'octstr', 'list',
'uint8', 'uint16', 'uint32', 'uint64',
'int8', 'int16', 'int32', 'int64'}
for matter_type, (tlv_type, rust_type) in MatterType.TYPE_MAP.items():
if matter_type not in excluded and rust_type and rust_type.startswith(('u', 'i')):
numeric_types.add(matter_type)
return numeric_types
NUMERIC_OR_ID_TYPES = _build_numeric_or_id_types()
def is_numeric_or_id_type(t: str) -> bool:
return t.startswith('uint') or t.startswith('int') or t in NUMERIC_OR_ID_TYPES
def build_numeric_field_assignment(
var_name: str,
field_id: int,
matter_type: str,
enums: Optional[Dict[str, 'MatterEnum']] = None,
indent: str = ' ',
item_var: str = 'item'
) -> str:
from .type_mapping import MatterType
rust_type = MatterType.get_rust_type(matter_type, enums=enums)
if rust_type == 'u64':
return f"{indent}{var_name}: {item_var}.get_int(&[{field_id}]),"
else:
return f"{indent}{var_name}: {item_var}.get_int(&[{field_id}]).map(|v| v as {rust_type}),"
def convert_to_snake_case(name: str) -> str:
replacements = [
('WiFi', 'Wifi'),
('RFID', 'Rfid'),
('HTTP', 'Http'),
('HTTPS', 'Https'),
('XML', 'Xml'),
('JSON', 'Json'),
('API', 'Api'),
('URL', 'Url'),
('URI', 'Uri'),
('UUID', 'Uuid'),
('TCP', 'Tcp'),
('UDP', 'Udp'),
('MAC', 'Mac'),
('DNS', 'Dns'),
('SSL', 'Ssl'),
('TLS', 'Tls'),
('PIN', 'Pin'),
('ACL', 'Acl'),
('ICD', 'Icd'),
('OTA', 'Ota'),
('PKI', 'Pki'),
('CO', 'Co')
]
for old, new in replacements:
name = name.replace(old, new)
name = re.sub(r'([A-Z]+)([A-Z][a-z])', r'\1_\2', name)
name = re.sub(r'([a-z\d])([A-Z])', r'\1_\2', name)
name = re.sub(r'_+', '_', name).lower()
return name.strip('_')
def convert_to_pascal_case(name: str) -> str:
if name and name[0].isupper():
return name
return ''.join(word.capitalize() for word in name.split('_'))
def escape_rust_keyword(name: str) -> str:
rust_keywords = {
'as', 'break', 'const', 'continue', 'crate', 'else', 'enum', 'extern',
'false', 'fn', 'for', 'if', 'impl', 'in', 'let', 'loop', 'match', 'mod',
'move', 'mut', 'pub', 'ref', 'return', 'self', 'Self', 'static', 'struct',
'super', 'trait', 'true', 'type', 'unsafe', 'use', 'where', 'while',
'async', 'await', 'dyn', 'abstract', 'become', 'box', 'do', 'final',
'macro', 'override', 'priv', 'typeof', 'unsized', 'virtual', 'yield',
'try', 'union'
}
if name in rust_keywords:
return f"{name}_"
return name
def _make_identifier(name: str) -> str:
if not name:
return name
if name[0].isdigit():
name = '_' + name
return name.replace(' ', '_').replace('.', '_').replace('-', '_').replace('/', '_')
def upper_ident(name: str) -> str:
return _make_identifier(name).upper()
def is_cross_cluster_struct(field_type: str, structs: Optional[Dict] = None) -> bool:
return field_type.endswith('Struct') and structs is not None and field_type not in structs
def should_skip_field(
field_type: str,
entry_type: Optional[str],
structs: Optional[Dict] = None
) -> bool:
if is_cross_cluster_struct(field_type, structs):
return True
if field_type == 'list' and entry_type and is_cross_cluster_struct(entry_type, structs):
return True
return False