import subprocess
import pandas as pd
TABLE_B_HEAD = """
//! This file is generated from BUFRCREX_TableB_en.txt.
use super::{XY, TableBEntry};
"""
TABLE_C_HEAD = """
//! This file is generated from BUFR_TableC_en.txt.
use super::TableCEntry;
"""
TABLE_D_HEAD = """
//! This file is generated from BUFR_TableD_en.txt.
use super::{Descriptor, XY, TableDEntry};
"""
def escape(s: str | float) -> str:
if isinstance(s, str):
return s.replace('"', '\\"')
elif isinstance(s, float):
return ""
else:
raise ValueError(f"Unknown type: {type(s)}")
def make_table_b() -> None:
df = pd.read_csv("./BUFR4/txt/BUFRCREX_TableB_en.txt")
with open("./src/tables/table_b.rs", "w") as f:
f.write(TABLE_B_HEAD)
f.write("\n")
f.write(f"pub static TABLE_B: [TableBEntry; {len(df)}] = [\n")
for _, row in df.iterrows():
if row["Status"] == "Deprecated": continue
fxy = row["FXY"] assert fxy < 1000000 x = (fxy % 100000) // 1000
y = fxy % 1000
f.write("TableBEntry {\n")
f.write(f"xy: XY {{ x: {x}, y: {y} }},\n")
f.write(f'class_name: "{row["ClassName_en"]}",\n')
f.write(f'element_name: "{escape(row["ElementName_en"])}",\n') f.write(f"scale: {row['BUFR_Scale']},\n")
f.write(f"reference_value: {row['BUFR_ReferenceValue']},\n")
unit = row["BUFR_Unit"] bits = row["BUFR_DataWidth_Bits"] if bits >= 33: assert unit == "CCITT IA5" f.write(f'unit: "{unit}",\n')
f.write(f"bits: {bits},\n")
f.write("},\n")
f.write("];")
def make_table_c() -> None:
df = pd.read_csv("./BUFR4/txt/BUFR_TableC_en.txt")
with open("./src/tables/table_c.rs", "w") as f:
f.write(TABLE_C_HEAD)
f.write("\n")
f.write(f"pub static TABLE_C: [TableCEntry; {len(df)}] = [\n")
for _, row in df.iterrows():
if row["Status"] == "Deprecated": continue
fxy = row["FXY"] assert fxy[0] == "2" x = int(str(fxy)[:3]) % 100 if isinstance(fxy, str) and fxy.endswith("YYY"):
y = None
else:
y = int(fxy) % 1000 f.write("TableCEntry {\n")
if y is None:
f.write(f"xy: ({x}, {None}),\n")
else:
f.write(f"xy: ({x}, Some({y})),\n")
f.write(f'operator_name: "{row["OperatorName_en"]}",\n')
f.write(f'operation_definition: "{row["OperationDefinition_en"]}",\n')
f.write("},\n")
f.write("];")
def make_table_d() -> None:
df = pd.read_csv("./BUFR4/txt/BUFR_TableD_en.txt")
count = 0
previous_fxy = None
closed = set()
with open("./src/tables/table_d.rs", "w") as f:
f.write(TABLE_D_HEAD)
f.write("\n")
size = df[df["Status"] != "Deprecated"].FXY1.nunique()
f.write(f"pub static TABLE_D: [TableDEntry; {size}] = [\n")
for _, row in df.iterrows():
if row["Status"] == "Deprecated": continue
fxy = row["FXY1"] if fxy == previous_fxy: count += 1
elif previous_fxy is not None:
assert previous_fxy not in closed
closed.add(previous_fxy)
count = 0
f.write("],\n")
f.write("},\n")
previous_fxy = fxy
x1 = (fxy % 100000) // 1000
y1 = fxy % 1000
fxy2 = row["FXY2"] f2 = fxy2 // 100000
x2 = (fxy2 % 100000) // 1000
y2 = fxy2 % 1000
if count == 0:
f.write("TableDEntry {\n")
f.write(f"xy: XY {{ x: {x1}, y: {y1} }},\n")
f.write(f'category: "{escape(row["CategoryOfSequences_en"])}",\n') f.write(
f'title: "{escape(row["Title_en"]).removeprefix("(").removesuffix(")")}",\n' )
f.write(f'sub_title: "{escape(row["SubTitle_en"])}",\n') f.write("elements: &[\n")
f.write(f"Descriptor {{ f: {f2}, x: {x2}, y: {y2} }},\n")
f.write("],\n")
if count > 0:
f.write("},\n")
f.write("];\n")
def main():
print("generating...")
make_table_b()
make_table_c()
make_table_d()
print("cargo fmt...")
subprocess.run(["cargo", "fmt"], check=True)
if __name__ == "__main__":
main()