-
-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathbuild.rs
More file actions
158 lines (139 loc) · 4.8 KB
/
Copy pathbuild.rs
File metadata and controls
158 lines (139 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
use std::env;
use std::error::Error;
use std::fmt::Write as _;
use std::fs;
use std::path::{Path, PathBuf};
use sdl3_sys::metadata::{self, Hint, Property, PropertyType as MetadataPropertyType};
fn main() {
#[cfg(any(target_os = "linux", target_os = "openbsd", target_os = "freebsd"))]
println!(r"cargo:rustc-link-search=/usr/local/lib");
if let Err(err) = generate_metadata_sources() {
panic!("failed to generate metadata sources: {err}");
}
}
fn generate_metadata_sources() -> Result<(), Box<dyn Error>> {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR is not set"));
println!("cargo:rerun-if-changed=build.rs");
generate_hint_names(&out_dir)?;
generate_property_names(&out_dir)?;
Ok(())
}
fn generate_hint_names(out_dir: &Path) -> Result<(), Box<dyn Error>> {
let mut output = String::new();
output.push_str("// @generated by build.rs; do not edit.\n\n");
let mut identifiers = Vec::new();
for hint in metadata::HINTS {
identifiers.push(generate_hint_definition(&mut output, hint)?);
}
writeln!(output, "pub const ALL: [&str; {}] = [", identifiers.len())?;
for ident in &identifiers {
writeln!(output, " {ident},")?;
}
output.push_str("];\n");
fs::write(out_dir.join("sdl3_hint_names.rs"), output)?;
Ok(())
}
fn generate_hint_definition(buf: &mut String, hint: &Hint) -> Result<String, Box<dyn Error>> {
if let Some(doc) = hint.doc {
append_doc_comment(buf, doc);
}
writeln!(buf, "#[doc(alias = {:?})]", hint.name)?;
writeln!(
buf,
"pub const {}: &str = {:?};",
hint.short_name,
hint.value_str()
)?;
buf.push('\n');
Ok(hint.short_name.to_string())
}
fn generate_property_names(out_dir: &Path) -> Result<(), Box<dyn Error>> {
let mut output = String::new();
output.push_str("// @generated by build.rs; do not edit.\n");
output.push_str("use super::{PropertyName, PropertyType, VersionTriple};\n\n");
let mut identifiers = Vec::new();
for property in metadata::PROPERTIES {
identifiers.push(generate_property_definition(&mut output, property)?);
}
output.push_str("pub const ALL: &[PropertyName] = &[\n");
for ident in &identifiers {
writeln!(output, " {ident},")?;
}
output.push_str("];\n");
fs::write(out_dir.join("sdl3_property_names.rs"), output)?;
Ok(())
}
fn generate_property_definition(
buf: &mut String,
property: &Property,
) -> Result<String, Box<dyn Error>> {
if let Some(doc) = property.doc {
append_doc_comment(buf, doc);
}
writeln!(buf, "#[doc(alias = {:?})]", property.name)?;
writeln!(
buf,
"pub const {}: PropertyName = PropertyName {{",
property.short_name
)?;
writeln!(buf, " module: {:?},", property.module)?;
writeln!(buf, " name: {:?},", property.name)?;
writeln!(buf, " short_name: {:?},", property.short_name)?;
writeln!(buf, " value: {:?},", property.value_str())?;
writeln!(
buf,
" raw: crate::sys::{}::{},",
property.module, property.name
)?;
writeln!(buf, " ty: {},", property_type_path(property.ty))?;
if let Some(doc) = property.doc {
writeln!(buf, " doc: Some({:?}),", doc)?;
} else {
buf.push_str(" doc: None,\n");
}
if let Some(version) = property.available_since {
let (major, minor, patch) = version_tuple(version);
writeln!(
buf,
" available_since: Some(VersionTriple {{ major: {major}, minor: {minor}, patch: {patch} }}),"
)?;
} else {
buf.push_str(" available_since: None,\n");
}
buf.push_str("};\n\n");
Ok(property.short_name.to_string())
}
fn append_doc_comment(buf: &mut String, doc: &str) {
for line in doc.trim_end().lines() {
if line.is_empty() {
buf.push_str("///\n");
} else {
buf.push_str("/// ");
buf.push_str(line);
buf.push('\n');
}
}
}
fn version_tuple(version: i32) -> (i32, i32, i32) {
let major = version / 1_000_000;
let minor = (version / 1_000) % 1_000;
let patch = version % 1_000;
(major, minor, patch)
}
fn property_type_path(ty: MetadataPropertyType) -> &'static str {
if ty == MetadataPropertyType::INVALID {
"PropertyType::INVALID"
} else if ty == MetadataPropertyType::POINTER {
"PropertyType::POINTER"
} else if ty == MetadataPropertyType::STRING {
"PropertyType::STRING"
} else if ty == MetadataPropertyType::NUMBER {
"PropertyType::NUMBER"
} else if ty == MetadataPropertyType::FLOAT {
"PropertyType::FLOAT"
} else if ty == MetadataPropertyType::BOOLEAN {
"PropertyType::BOOLEAN"
} else {
panic!("unknown property type {}", ty.0);
}
}