import json
import sys
from pathlib import Path

TYPE_ENUM_ENTRY_TEMPLATE = "\
    %(enum_id)s(%(enum_type)s),\n"

ID_ENUM_ENTRY_TEMPLATE = "\
    %(enum_id)s = %(enum_value)#04x,\n"

ID_TRY_FROM_MATCH_ENTRY_TEMPLATE = "\
    x if x == SEOutputDataId::%(enum_id)s as u16 => Ok(SEOutputDataId::%(enum_id)s),\n"

OUTPUT_TEMPLATE = """
// NOTE: this file is generated by generate_output_data.py

use super::types::*;

#[derive(Debug, PartialEq)]
pub enum SEOutputData {
    %(type_enum_entries)s
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u16)]
pub enum SEOutputDataId {
    %(id_enum_entries)s
}

impl std::convert::TryFrom<u16> for SEOutputDataId {
    type Error = ();

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match value {
            %(try_from_match_entries)s
            _ => unimplemented!("{:#x}", value),
        }
    }
}
"""

SEP_TO_RUST_DATA_TYPE = {
    "SEType_u8": "SETypeU8",
    "SEType_u16": "SETypeU16",
    "SEType_u32": "SETypeU32",
    "SEType_u64": "SETypeU64",
    "SEType_float": "SETypeFloat",
    "SEType_f64": "SETypeF64",
    "SEType_Vector": "SETypeVector",
    "SEType_Point2D": "SETypePoint2D",
    "SEType_Point3D": "SETypePoint3D",
    "SEType_Vect3D": "SETypeVect3D",
    "SEType_String": "SETypeString",
    "SEType_Quaternion": "SETypeQuaternion",
    "SEType_UserMarker": "SETypeUserMarker",
    "SEType_WorldIntersection": "SETypeWorldIntersection",
    "SEType_WorldIntersections": "SETypeWorldIntersections",
}


def main():
    data_output_json = Path(sys.argv[1])
    out_file = Path(sys.argv[2])
    assert (data_output_json.is_file())

    with data_output_json.open() as f:
        output_data_definitions = json.load(f)

    type_enum_entries = ""
    id_enum_entries = ""
    id_try_from_match_entries = ""
    for d in output_data_definitions:
        enum_id = d["EnumID"]
        enum_number = int(d["EnumNumber"], 16)
        data_type = SEP_TO_RUST_DATA_TYPE[d["DataType"]]
        required_module = d["RequiredModule"]

        if required_module == "FacialFeatures":
            # TODO: maybe support FacialFeatures module in the future..?
            continue

        type_enum_entries += TYPE_ENUM_ENTRY_TEMPLATE % {
            'enum_id': enum_id, 'enum_type': data_type
        }
        id_enum_entries += ID_ENUM_ENTRY_TEMPLATE % {
            'enum_id': enum_id,
            'enum_value': enum_number
        }
        id_try_from_match_entries += ID_TRY_FROM_MATCH_ENTRY_TEMPLATE % {
            'enum_id': enum_id
        }

    file_content = OUTPUT_TEMPLATE % {
        'type_enum_entries': type_enum_entries,
        'id_enum_entries': id_enum_entries,
        'try_from_match_entries': id_try_from_match_entries
    }
    out_file.write_text(file_content)


if __name__ == "__main__":
    main()

import json
import sys
from pathlib import Path

TYPE_ENUM_ENTRY_TEMPLATE = "\
    %(enum_id)s(%(enum_type)s),\n"

ID_ENUM_ENTRY_TEMPLATE = "\
    %(enum_id)s = %(enum_value)#04x,\n"

ID_TRY_FROM_MATCH_ENTRY_TEMPLATE = "\
    x if x == SEOutputDataId::%(enum_id)s as u16 => Ok(SEOutputDataId::%(enum_id)s),\n"

OUTPUT_TEMPLATE = """
// NOTE: this file is generated by generate_output_data.py

use super::types::*;

#[derive(Debug, PartialEq)]
pub enum SEOutputData {
    %(type_enum_entries)s
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u16)]
pub enum SEOutputDataId {
    %(id_enum_entries)s
}

impl std::convert::TryFrom<u16> for SEOutputDataId {
    type Error = ();

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match value {
            %(try_from_match_entries)s
            _ => unimplemented!("{:#x}", value),
        }
    }
}
"""

SEP_TO_RUST_DATA_TYPE = {
    "SEType_u8": "SETypeU8",
    "SEType_u16": "SETypeU16",
    "SEType_u32": "SETypeU32",
    "SEType_u64": "SETypeU64",
    "SEType_float": "SETypeFloat",
    "SEType_f64": "SETypeF64",
    "SEType_Vector": "SETypeVector",
    "SEType_Point2D": "SETypePoint2D",
    "SEType_Point3D": "SETypePoint3D",
    "SEType_Vect3D": "SETypeVect3D",
    "SEType_String": "SETypeString",
    "SEType_Quaternion": "SETypeQuaternion",
    "SEType_UserMarker": "SETypeUserMarker",
    "SEType_WorldIntersection": "SETypeWorldIntersection",
    "SEType_WorldIntersections": "SETypeWorldIntersections",
}


def main():
    data_output_json = Path(sys.argv[1])
    out_file = Path(sys.argv[2])
    assert (data_output_json.is_file())

    with data_output_json.open() as f:
        output_data_definitions = json.load(f)

    type_enum_entries = ""
    id_enum_entries = ""
    id_try_from_match_entries = ""
    for d in output_data_definitions:
        enum_id = d["EnumID"]
        enum_number = int(d["EnumNumber"], 16)
        data_type = SEP_TO_RUST_DATA_TYPE[d["DataType"]]
        required_module = d["RequiredModule"]

        if required_module == "FacialFeatures":
            # TODO: maybe support FacialFeatures module in the future..?
            continue

        type_enum_entries += TYPE_ENUM_ENTRY_TEMPLATE % {
            'enum_id': enum_id, 'enum_type': data_type
        }
        id_enum_entries += ID_ENUM_ENTRY_TEMPLATE % {
            'enum_id': enum_id,
            'enum_value': enum_number
        }
        id_try_from_match_entries += ID_TRY_FROM_MATCH_ENTRY_TEMPLATE % {
            'enum_id': enum_id
        }

    file_content = OUTPUT_TEMPLATE % {
        'type_enum_entries': type_enum_entries,
        'id_enum_entries': id_enum_entries,
        'try_from_match_entries': id_try_from_match_entries
    }
    out_file.write_text(file_content)


if __name__ == "__main__":
    main()

#04x,\n" // NOTE: this file is generated by generate_output_data.py  use super::types::*;  #[derive(Debug, PartialEq)] pub enum SEOutputData {     %(type_enum_entries)s }  #[derive(Debug, PartialEq, Eq, Clone, Copy)] #[repr(u16)] pub enum SEOutputDataId {     %(id_enum_entries)s }  impl std::convert::TryFrom<u16> for SEOutputDataId {     type Error = ();      fn try_from(value: u16) -> Result<Self, Self::Error> {         match value {             %(try_from_match_entries)s             _ => unimplemented!("{:#x}", value),         }     } } # TODO: maybe support FacialFeatures module in the future..?