Skip to content

Commit f5e68e8

Browse files
committed
Move GDScript templating logic to repo-tweak, too
1 parent dcf5951 commit f5e68e8

File tree

5 files changed

+112
-153
lines changed

5 files changed

+112
-153
lines changed

itest/repo-tweak/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
name = "repo-tweak"
33
version = "0.1.0"
44
edition = "2021"
5+
rust-version = "1.78"
6+
license = "MPL-2.0"
57
publish = false
68

7-
[dependencies]
9+
# Note: this acts as both library and binary.

itest/repo-tweak/src/lib.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright (c) godot-rust; Bromeon and contributors.
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
use std::collections::HashMap;
9+
10+
#[derive(Debug)]
11+
pub struct Match {
12+
/// Position before pattern start marker.
13+
pub before_start: usize,
14+
15+
/// Position at the beginning of the repetition (after marker + keys).
16+
pub start: usize,
17+
18+
/// Position 1 past the end of the repetition.
19+
pub end: usize,
20+
21+
/// Position after the end pattern marker.
22+
pub after_end: usize,
23+
24+
/// Extra keys following the start pattern marker.
25+
pub key_values: HashMap<String, String>,
26+
}
27+
28+
pub fn find_repeated_ranges(
29+
entire: &str,
30+
start_pat: &str,
31+
end_pat: &str,
32+
keys: &[&str],
33+
retain_end_pat: bool,
34+
) -> Vec<Match> {
35+
let mut search_start = 0;
36+
let mut found = vec![];
37+
38+
while let Some(start) = entire[search_start..].find(start_pat) {
39+
let before_start = search_start + start;
40+
let start = before_start + start_pat.len();
41+
42+
let mut key_values = HashMap::new();
43+
44+
let Some(end) = entire[start..].find(end_pat) else {
45+
panic!("unmatched start pattern '{start_pat}' without end");
46+
};
47+
48+
let end = start + end;
49+
let end = if retain_end_pat {
50+
// Rewind until previous newline.
51+
entire[..end + 1].rfind('\n').unwrap_or(end)
52+
} else {
53+
end
54+
};
55+
56+
let after_end = end + end_pat.len();
57+
58+
let within = &entire[start..end];
59+
println!("Within: <<{within}>>");
60+
61+
let mut after_keys = start;
62+
for key in keys {
63+
let key_fmt = format!("[{key}] ");
64+
65+
println!(" Find '{key_fmt}' -> {:?}", within.find(&key_fmt));
66+
67+
let Some(pos) = within.find(&key_fmt) else {
68+
continue;
69+
};
70+
71+
let pos = pos + key_fmt.len();
72+
73+
// Read until end of line -> that's the value.
74+
let eol = within[pos..]
75+
.find(['\n', '\r'])
76+
.expect("unterminated line for key");
77+
78+
let value = &within[pos..pos + eol];
79+
key_values.insert(key.to_string(), value.to_string());
80+
81+
after_keys = after_keys.max(start + pos + eol);
82+
}
83+
84+
println!("Found {start}..{end}");
85+
found.push(Match {
86+
before_start,
87+
start: after_keys,
88+
end,
89+
after_end,
90+
key_values,
91+
});
92+
search_start = after_end;
93+
}
94+
95+
found
96+
}

itest/repo-tweak/src/main.rs

Lines changed: 10 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::fs::File;
1010
use std::io::Write;
1111
use std::path::Path;
1212

13+
// Manual input.
1314
#[rustfmt::skip]
1415
pub const GODOT_LATEST_PATCH_VERSIONS: &[&str] = &[
1516
"4.0.4",
@@ -20,6 +21,11 @@ pub const GODOT_LATEST_PATCH_VERSIONS: &[&str] = &[
2021

2122
// ----------------------------------------------------------------------------------------------------------------------------------------------
2223

24+
// Use lib.rs as module; so we don't need another crate just for that.
25+
// Lint #[allow(special_module_name)] is broken, thus rename.
26+
#[path = "lib.rs"]
27+
mod library;
28+
2329
fn main() {
2430
let workspace_dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."));
2531
sync_versions_recursive(workspace_dir, true);
@@ -55,7 +61,8 @@ fn sync_versions_recursive(parent_dir: &Path, top_level: bool) {
5561
let content = std::fs::read_to_string(&path).expect("read file");
5662

5763
let keys = ["repeat", "fmt", "pre", "post"];
58-
let ranges = find_repeated_ranges(&content, "[version-sync] [[", "]]", &keys);
64+
let ranges =
65+
library::find_repeated_ranges(&content, "[version-sync] [[", "]]", &keys, true);
5966

6067
let mut last_pos = 0;
6168
if !ranges.is_empty() {
@@ -173,78 +180,8 @@ fn substitute_template(
173180
}
174181

175182
fn apply_char_substitutions(s: &str) -> String {
176-
s.replace("\\t", "\t").replace("\\n", "\n")
177-
}
178-
179-
fn find_repeated_ranges(entire: &str, start_pat: &str, end_pat: &str, keys: &[&str]) -> Vec<Match> {
180-
let mut search_start = 0;
181-
let mut found = vec![];
182-
183-
while let Some(start) = entire[search_start..].find(start_pat) {
184-
let before_start = search_start + start;
185-
let start = before_start + start_pat.len();
186-
187-
let mut key_values = HashMap::new();
188-
189-
let Some(end) = entire[start..].find(end_pat) else {
190-
panic!("unmatched start pattern '{start_pat}' without end");
191-
};
192-
193-
let end = start + end;
194-
// Rewind until previous newline.
195-
let end = entire[..end].rfind('\n').unwrap_or(end);
196-
let after_end = end + end_pat.len();
197-
let within = &entire[start..end];
198-
199-
let mut after_keys = start;
200-
for key in keys {
201-
let key_fmt = format!("[{key}] ");
202-
203-
println!(" Find '{key_fmt}' -> {:?}", within.find(&key_fmt));
204-
205-
let Some(pos) = within.find(&key_fmt) else {
206-
continue;
207-
};
208-
209-
let pos = pos + key_fmt.len();
210-
211-
// Read until end of line -> that's the value.
212-
let eol = within[pos..]
213-
.find(&['\n', '\r'])
214-
.expect("unterminated line for key");
215-
216-
let value = &within[pos..pos + eol];
217-
key_values.insert(key.to_string(), value.to_string());
218-
219-
after_keys = after_keys.max(start + pos + eol);
220-
}
221-
222-
println!("Found {start}..{end}");
223-
found.push(Match {
224-
before_start,
225-
start: after_keys,
226-
end,
227-
after_end,
228-
key_values,
229-
});
230-
search_start = after_end;
231-
}
232-
233-
found
234-
}
235-
236-
#[derive(Debug)]
237-
struct Match {
238-
/// Position before pattern start marker.
239-
before_start: usize,
240-
/// Position at the beginning of the repetition (after marker + keys).
241-
start: usize,
242-
/// Position 1 past the end of the repetition.
243-
end: usize,
244-
/// Position after the end pattern marker.
245-
after_end: usize,
246-
/// Extra keys following the start pattern marker.
247-
key_values: HashMap<String, String>,
183+
s.replace("\\t", " ") // Not \t due to rustfmt.
184+
.replace("\\n", "\n")
248185
}
249186

250187
fn latest_patch_versions() -> Vec<(u8, u8)> {

itest/rust/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ serde_json = { version = "1.0", optional = true }
2525

2626
[build-dependencies]
2727
godot-bindings = { path = "../../godot-bindings" } # emit_godot_version_cfg
28+
repo-tweak = { path = "../repo-tweak" }
29+
2830
# Minimum versions compatible with -Zminimal-versions
2931
proc-macro2 = "1.0.63"
3032
quote = "1.0.29"

itest/rust/build.rs

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
use proc_macro2::TokenStream;
99
use quote::{format_ident, quote};
10-
use std::collections::HashMap;
1110
use std::io::Write;
1211
use std::path::Path;
1312

@@ -561,7 +560,7 @@ fn write_gdscript_code(
561560
// let (mut last_start, mut prev_end) = (0, 0);
562561
let mut last = 0;
563562

564-
let ranges = find_repeated_ranges(&template, "#(", "#)", &[]);
563+
let ranges = repo_tweak::find_repeated_ranges(&template, "#(", "#)", &[], false);
565564
for m in ranges {
566565
file.write_all(template[last..m.before_start].as_bytes())?;
567566

@@ -600,80 +599,3 @@ fn replace_parts(
600599

601600
Ok(())
602601
}
603-
604-
// FIXME deduplicate
605-
fn find_repeated_ranges(entire: &str, start_pat: &str, end_pat: &str, keys: &[&str]) -> Vec<Match> {
606-
let mut search_start = 0;
607-
let mut found = vec![];
608-
609-
while let Some(start) = entire[search_start..].find(start_pat) {
610-
let before_start = search_start + start;
611-
let start = before_start + start_pat.len();
612-
613-
let mut key_values = HashMap::new();
614-
615-
let Some(end) = entire[start..].find(end_pat) else {
616-
panic!("unmatched start pattern '{start_pat}' without end");
617-
};
618-
619-
let end = start + end;
620-
// Rewind until previous newline.
621-
let end = entire[..end].rfind('\n').unwrap_or(end);
622-
623-
let after_end = end + end_pat.len();
624-
625-
let within = &entire[start..end];
626-
println!("Within: <<{within}>>");
627-
628-
let mut after_keys = start;
629-
for key in keys {
630-
let key_fmt = format!("[{key}] ");
631-
632-
println!(" Find '{key_fmt}' -> {:?}", within.find(&key_fmt));
633-
634-
let Some(pos) = within.find(&key_fmt) else {
635-
continue;
636-
};
637-
638-
let pos = pos + key_fmt.len();
639-
640-
// Read until end of line -> that's the value.
641-
let eol = within[pos..]
642-
.find(&['\n', '\r'])
643-
.expect("unterminated line for key");
644-
645-
let value = &within[pos..pos + eol];
646-
key_values.insert(key.to_string(), value.to_string());
647-
648-
after_keys = after_keys.max(start + pos + eol);
649-
}
650-
651-
println!("Found {start}..{end}");
652-
found.push(Match {
653-
before_start,
654-
start: after_keys,
655-
end,
656-
after_end,
657-
key_values,
658-
});
659-
search_start = after_end;
660-
}
661-
662-
found
663-
}
664-
665-
// FIXME deduplicate
666-
#[derive(Debug)]
667-
struct Match {
668-
/// Position before pattern start marker.
669-
before_start: usize,
670-
/// Position at the beginning of the repetition (after marker + keys).
671-
start: usize,
672-
/// Position 1 past the end of the repetition.
673-
end: usize,
674-
/// Position after the end pattern marker.
675-
after_end: usize,
676-
/// Extra keys following the start pattern marker.
677-
#[allow(dead_code)]
678-
key_values: HashMap<String, String>,
679-
}

0 commit comments

Comments
 (0)