[WIP] Version Parsing

This commit is contained in:
Alex Emmet 2026-06-22 14:39:18 +02:00
commit 907b9f04db
9 changed files with 133 additions and 40 deletions

View file

@ -151,15 +151,25 @@ const RESERVED_DATA_TYPES: &[ReservedEntry] = &[
];
fn main() {
let config_path = std::env::var("MTP_TYPE_MAPS").expect(
"MTP_TYPE_MAPS environment variable must be set to the path of a type-maps.yaml file",
);
let content = std::fs::read_to_string(&config_path).expect("Failed to read type-maps.yaml");
let config: Config = serde_yaml::from_str(&content).expect("Failed to parse type-maps.yaml");
let out = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
let config = match std::env::var("MTP_TYPE_MAPS") {
Ok(config_path) => {
let content =
std::fs::read_to_string(&config_path).expect("Failed to read type-maps.yaml");
serde_yaml::from_str(&content).expect("Failed to parse type-maps.yaml")
}
Err(_) => {
eprintln!(
"warning: MTP_TYPE_MAPS not set; generating types with reserved entries only"
);
Config {
protocol_version: String::new(),
type_maps: BTreeMap::new(),
}
}
};
let code = generate(&config);
std::fs::write(out.join("types.rs"), code).unwrap();
}
@ -187,7 +197,7 @@ fn generate(config: &Config) -> String {
let mut out = String::new();
writeln!(
out,
"// Auto-generated by type-map/build.rs, they should not be edited manually"
"// Auto-generated by type-map/build.rs, this file should not be edited manually"
)
.unwrap();
writeln!(out).unwrap();
@ -206,15 +216,39 @@ fn generate(config: &Config) -> String {
let sorted = sorted_versions(config);
generate_protocol_version(&mut out, config);
generate_comm_type_enum(&mut out, &all_comm_names);
generate_data_type_enum(&mut out, &all_data_names);
generate_type_map_constructors(&mut out, &sorted);
generate_lookup_methods(&mut out, config, &sorted);
generate_builtin_type_maps(&mut out, &sorted);
generate_enum_conversion_methods(&mut out, &sorted);
out
}
fn generate_protocol_version(out: &mut String, config: &Config) {
let (major, minor) = if config.protocol_version.is_empty() {
(0, 0)
} else {
let parts: Vec<&str> = config.protocol_version.split('.').collect();
if parts.len() == 2 {
let maj = parts[0].parse::<u16>().unwrap_or(0);
let min = parts[1].parse::<u16>().unwrap_or(0);
(maj, min)
} else {
(0, 0)
}
};
writeln!(
out,
"pub const PROTOCOL_VERSION: Version = Version({}, {});",
major, minor
)
.unwrap();
writeln!(out).unwrap();
}
fn generate_comm_type_enum(out: &mut String, user_names: &BTreeSet<&str>) {
writeln!(
out,
@ -343,6 +377,22 @@ fn generate_type_map_constructors(out: &mut String, sorted_versions: &[(String,
writeln!(out, "}}").unwrap();
writeln!(out).unwrap();
}
let (latest_major, latest_minor) = match sorted_versions.last() {
Some((_key, major, minor)) => (*major, *minor),
None => (0, 0),
};
writeln!(out, "impl TypeMap {{").unwrap();
writeln!(out, " pub fn latest() -> Self {{").unwrap();
writeln!(
out,
" Self {{ version: Version({}, {}) }}",
latest_major, latest_minor
)
.unwrap();
writeln!(out, " }}").unwrap();
writeln!(out, "}}").unwrap();
writeln!(out).unwrap();
}
fn generate_lookup_methods(
@ -351,7 +401,7 @@ fn generate_lookup_methods(
sorted_versions: &[(String, u16, u16)],
) {
// comm_id_enum
writeln!(out, "#[allow(unreachable_patterns)]").unwrap();
writeln!(out, "#[allow(unreachable_patterns, unused_variables)]").unwrap();
writeln!(out, "impl TypeMap {{").unwrap();
writeln!(
out,
@ -392,6 +442,7 @@ fn generate_lookup_methods(
writeln!(out).unwrap();
// data_id_enum
writeln!(out, " #[allow(unused_variables)]").unwrap();
writeln!(
out,
" pub fn data_id_enum(&self, dt: DataType) -> Option<u16> {{"
@ -438,3 +489,27 @@ fn generate_builtin_type_maps(out: &mut String, sorted_versions: &[(String, u16,
writeln!(out, "}}").unwrap();
writeln!(out).unwrap();
}
fn generate_enum_conversion_methods(out: &mut String, _sorted_versions: &[(String, u16, u16)]) {
writeln!(out, "impl CommunicationType {{").unwrap();
writeln!(out, " pub fn to_id(self, tm: &TypeMap) -> CommunicationTypeId {{").unwrap();
writeln!(
out,
" CommunicationTypeId(tm.comm_id_enum(self).expect(\"CommunicationType not found in this TypeMap version\"))"
)
.unwrap();
writeln!(out, " }}").unwrap();
writeln!(out, "}}").unwrap();
writeln!(out).unwrap();
writeln!(out, "impl DataType {{").unwrap();
writeln!(out, " pub fn to_id(self, tm: &TypeMap) -> DataTypeId {{").unwrap();
writeln!(
out,
" DataTypeId(tm.data_id_enum(self).expect(\"DataType not found in this TypeMap version\"))"
)
.unwrap();
writeln!(out, " }}").unwrap();
writeln!(out, "}}").unwrap();
writeln!(out).unwrap();
}