Skip to content

Commit e7726b5

Browse files
committed
Refactor icon extraction logic in build.rs to improve performance and memory usage. The download_tabler_icons function now directly processes sprite content in memory, eliminating the need for temporary file storage. Updated extract_icons_from_sprite to handle byte slices instead of strings, enhancing efficiency.
1 parent df1e6c2 commit e7726b5

File tree

1 file changed

+18
-32
lines changed

1 file changed

+18
-32
lines changed

build.rs

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,12 @@ fn make_url_path(url: &str) -> PathBuf {
179179
async fn download_tabler_icons(client: Rc<awc::Client>, sprite_url: &str) {
180180
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
181181
let icon_map_path = out_dir.join("icons.rs");
182-
183-
if !icon_map_path.exists() {
184-
let cached_sprite_path = make_url_path(sprite_url);
185-
download_url_to_path(&client, sprite_url, &cached_sprite_path).await;
186-
generate_icons_rs(&icon_map_path, &cached_sprite_path);
187-
}
182+
let mut sprite_content = Vec::with_capacity(3 * 1024 * 1024);
183+
copy_url_to_opened_file(&client, sprite_url, &mut sprite_content).await;
184+
generate_icons_rs(&icon_map_path, &sprite_content);
188185
}
189186

190-
fn generate_icons_rs(icon_map_path: &Path, cached_sprite_path: &Path) {
191-
let sprite_content = std::fs::read_to_string(cached_sprite_path).unwrap();
187+
fn generate_icons_rs(icon_map_path: &Path, sprite_content: &[u8]) {
192188
let mut file = File::create(icon_map_path).unwrap();
193189

194190
writeln!(
@@ -206,36 +202,26 @@ fn generate_icons_rs(icon_map_path: &Path, cached_sprite_path: &Path) {
206202
.unwrap();
207203
writeln!(file, "let mut m = HashMap::new();").unwrap();
208204

209-
extract_icons_from_sprite(&sprite_content, |name, content| {
205+
extract_icons_from_sprite(sprite_content, |name, content| {
210206
writeln!(file, "m.insert({name:?}, r#\"{content}\"#);").unwrap();
211207
});
212208
writeln!(file, "m}});").unwrap();
213209
}
214210

215-
fn extract_icons_from_sprite(sprite_content: &str, mut callback: impl FnMut(&str, &str)) {
216-
let mut pos = 0;
217-
while let Some(symbol_start) = sprite_content[pos..].find("<symbol") {
218-
let symbol_start = pos + symbol_start;
219-
let Some(symbol_end) = sprite_content[symbol_start..].find("</symbol>") else {
220-
break;
221-
};
222-
let symbol_end = symbol_start + symbol_end + "</symbol>".len();
223-
224-
let symbol_tag = &sprite_content[symbol_start..symbol_end];
225-
226-
if let Some(id_start) = symbol_tag.find("id=\"tabler-") {
227-
let id_start = id_start + "id=\"tabler-".len();
228-
if let Some(id_end) = symbol_tag[id_start..].find('"') {
229-
let icon_name = &symbol_tag[id_start..id_start + id_end];
230-
231-
let content_start = symbol_tag.find('>').unwrap() + 1;
232-
let content_end = symbol_tag.rfind("</symbol>").unwrap();
233-
let inner_content = symbol_tag[content_start..content_end].trim();
234-
235-
callback(icon_name, inner_content);
236-
}
211+
fn extract_icons_from_sprite(sprite_content: &[u8], mut callback: impl FnMut(&str, &str)) {
212+
let mut sprite_str = std::str::from_utf8(sprite_content).unwrap();
213+
fn take_between<'a>(s: &mut &'a str, start: &str, end: &str) -> Option<&'a str> {
214+
let start_index = s.find(start)?;
215+
let end_index = s[start_index + start.len()..].find(end)?;
216+
let result = &s[start_index + start.len()..][..end_index];
217+
*s = &s[start_index + start.len() + end_index + end.len()..];
218+
Some(result)
219+
}
220+
while let Some(mut symbol_tag) = take_between(&mut sprite_str, "<symbol", "</symbol>") {
221+
if let Some(id) = take_between(&mut symbol_tag, "id=\"tabler-", "\"") {
222+
let content_start = symbol_tag.find('>').unwrap() + 1;
223+
callback(id, &symbol_tag[content_start..]);
237224
}
238-
pos = symbol_end;
239225
}
240226
}
241227

0 commit comments

Comments
 (0)