56 lines
1.5 KiB
Python
56 lines
1.5 KiB
Python
from __future__ import annotations
|
|
from dataclasses import dataclass, field
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class Field:
|
|
name: str
|
|
level: int
|
|
pic: str
|
|
usage: str = "DISPLAY"
|
|
offset: int = 0
|
|
length: int = 0
|
|
decimal: int = 0
|
|
signed: bool = False
|
|
sign_separate: bool = False
|
|
occurs: Optional[int] = None
|
|
occurs_max: Optional[int] = None
|
|
redefines: Optional[str] = None
|
|
redefines_variant: Optional[str] = None
|
|
conditions: list[dict] = field(default_factory=list)
|
|
children: list["Field"] = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class FieldTree:
|
|
fields: list[Field] = field(default_factory=list)
|
|
copybook_name: str = ""
|
|
sha256: str = ""
|
|
|
|
def flatten(self) -> dict[str, Field]:
|
|
result = {}
|
|
def _walk(ff):
|
|
for f in ff:
|
|
result[f.name] = f
|
|
_walk(f.children)
|
|
_walk(self.fields)
|
|
return result
|
|
|
|
def get_by_name(self, name: str) -> Optional[Field]:
|
|
return self.flatten().get(name)
|
|
|
|
@classmethod
|
|
def from_list(cls, fields: list[Field], name: str = "") -> "FieldTree":
|
|
return cls(fields=fields, copybook_name=name)
|
|
|
|
|
|
_f = Field(name="BR-AMT", level=5, pic="S9(7)V99", usage="COMP-3", offset=0, length=5, decimal=2, signed=True)
|
|
assert _f.name == "BR-AMT"
|
|
assert _f.decimal == 2
|
|
assert _f.signed
|
|
|
|
_ft = FieldTree(fields=[_f], copybook_name="BILLCPY")
|
|
assert "BR-AMT" in _ft.flatten()
|
|
assert _ft.get_by_name("BR-AMT") is _f
|