aboutsummaryrefslogtreecommitdiff
path: root/stm32-gen-features/src
diff options
context:
space:
mode:
authorCôme ALLART <[email protected]>2021-09-05 20:03:52 +0200
committerCôme ALLART <[email protected]>2021-09-05 20:19:13 +0200
commitaddee8778df6fb185a0a23658eef215ff2415d6e (patch)
tree41db62dd8951dade2f09ff831b0c1952c41b1e76 /stm32-gen-features/src
parent022b8092485c39cd68ad4e259ced5253b8a59460 (diff)
refactor(gen-features): use Rust instead of Python
Added support for /stm32-metapac
Diffstat (limited to 'stm32-gen-features/src')
-rw-r--r--stm32-gen-features/src/lib.rs143
-rw-r--r--stm32-gen-features/src/main.rs16
2 files changed, 107 insertions, 52 deletions
diff --git a/stm32-gen-features/src/lib.rs b/stm32-gen-features/src/lib.rs
index b20a1ba4a..683d0d4ed 100644
--- a/stm32-gen-features/src/lib.rs
+++ b/stm32-gen-features/src/lib.rs
@@ -1,17 +1,16 @@
1use std::{ 1//! FIXME discuss about which errors to print and when to panic
2 collections::HashMap, 2
3 path::{Path, PathBuf}, 3use std::{collections::HashMap, iter::FilterMap, path::Path, slice::Iter};
4};
5 4
6const SUPPORTED_FAMILIES: [&str; 8] = [ 5const SUPPORTED_FAMILIES: [&str; 8] = [
7 "STM32F0", 6 "stm32f0",
8 "STM32F4", 7 "stm32f4",
9 "STM32G0", 8 "stm32g0",
10 "STM32L0", 9 "stm32l0",
11 "STM32L4", 10 "stm32l4",
12 "STM32H7", 11 "stm32h7",
13 "STM32WB55", 12 "stm32wb55",
14 "STM32WL55", 13 "stm32wl55",
15]; 14];
16 15
17const SEPARATOR_START: &str = "# BEGIN GENERATED FEATURES\n"; 16const SEPARATOR_START: &str = "# BEGIN GENERATED FEATURES\n";
@@ -25,25 +24,36 @@ fn is_supported(name: &str) -> bool {
25 .any(|family| name.starts_with(family)) 24 .any(|family| name.starts_with(family))
26} 25}
27 26
28/// Get the yaml file names and the associated chip names for supported chips 27type SupportedIter<'a> = FilterMap<
28 Iter<'a, (String, Vec<String>)>,
29 fn(&(String, Vec<String>)) -> Option<(&String, &Vec<String>)>,
30>;
31trait FilterSupported {
32 fn supported(&self) -> SupportedIter;
33}
34impl FilterSupported for &[(String, Vec<String>)] {
35 /// Get a new Vec with only the supported chips
36 fn supported(&self) -> SupportedIter {
37 self.iter()
38 .filter_map(|(name, cores)| is_supported(name).then(|| (name, cores)))
39 }
40}
41
42/// Get the list of all the chips and their supported cores
29/// 43///
30/// Print errors to `stderr` when something is returned by the glob but is not in the returned 44/// Print errors to `stderr` when something is returned by the glob but is not in the returned
31/// [`Vec`] 45/// [`Vec`]
32fn supported_chip_yaml_files_with_names() -> Vec<(PathBuf, String)> { 46///
47/// This function is slow because all the yaml files are parsed.
48pub fn chip_names_and_cores() -> Vec<(String, Vec<String>)> {
33 glob::glob("../stm32-data/data/chips/*.yaml") 49 glob::glob("../stm32-data/data/chips/*.yaml")
34 .expect("bad glob pattern") 50 .unwrap()
35 .filter_map(|entry| entry.map_err(|e| eprintln!("{:?}", e)).ok()) 51 .filter_map(|entry| entry.map_err(|e| eprintln!("{:?}", e)).ok())
36 .filter_map(|entry| { 52 .filter_map(|entry| {
37 if let Some(name) = entry.file_stem().and_then(|stem| stem.to_str()) { 53 if let Some(name) = entry.file_stem().and_then(|stem| stem.to_str()) {
38 if is_supported(name) { 54 Some((name.to_lowercase(), chip_cores(&entry)))
39 let owned_name = name.to_lowercase();
40 Some((entry, owned_name))
41 } else {
42 eprintln!("{} is not supported", name);
43 None
44 }
45 } else { 55 } else {
46 eprintln!("{:?} is not a regural file", entry); 56 eprintln!("{:?} is not a regular file", entry);
47 None 57 None
48 } 58 }
49 }) 59 })
@@ -53,36 +63,71 @@ fn supported_chip_yaml_files_with_names() -> Vec<(PathBuf, String)> {
53/// Get the list of the cores of a chip by its associated file 63/// Get the list of the cores of a chip by its associated file
54/// 64///
55/// # Panic 65/// # Panic
56/// Panics if the file does not exist or if it contains yaml syntax errors 66/// Panics if the file does not exist or if it contains yaml syntax errors.
57/// 67/// Panics if "cores" is not an array.
58/// # None 68fn chip_cores(path: &Path) -> Vec<String> {
59/// Returns none if "cores" is not an array
60fn chip_cores(path: &Path) -> Option<Vec<yaml_rust::Yaml>> {
61 let file_contents = std::fs::read_to_string(path).unwrap(); 69 let file_contents = std::fs::read_to_string(path).unwrap();
62 let doc = &yaml_rust::YamlLoader::load_from_str(&file_contents).unwrap()[0]; 70 let doc = &yaml_rust::YamlLoader::load_from_str(&file_contents).unwrap()[0];
63 doc["cores"].as_vec().cloned() 71 doc["cores"]
72 .as_vec()
73 .unwrap_or_else(|| panic!("{:?}:[cores] is not an array", path))
74 .iter()
75 .enumerate()
76 .map(|(i, core)| {
77 core["name"]
78 .as_str()
79 .unwrap_or_else(|| panic!("{:?}:[cores][{}][name] is not a string", path, i))
80 .to_owned()
81 })
82 .collect()
64} 83}
65 84
66/// Load the list of chips 85/// Generate data needed in `../embassy-stm32/Cargo.toml`
86///
87/// Print errors to `stderr` when something is returned by the glob but is not in the returned
88/// [`Vec`]
67/// 89///
68/// # Panic 90/// # Panic
69/// Panics if a file contains yaml syntax errors or if a value does not have a consistent type 91/// Panics if a file contains yaml syntax errors or if a value does not have a consistent type
70pub fn load_chip_list() -> HashMap<String, Vec<String>> { 92pub fn embassy_stm32_needed_data(
93 names_and_cores: &[(String, Vec<String>)],
94) -> HashMap<String, Vec<String>> {
71 let mut result = HashMap::new(); 95 let mut result = HashMap::new();
72 for (path, name) in supported_chip_yaml_files_with_names() { 96 for (chip_name, cores) in names_and_cores.supported() {
73 let cores = chip_cores(&path).unwrap_or_else(|| panic!("{}[cores] is not an array", name));
74 if cores.len() > 1 { 97 if cores.len() > 1 {
75 for (i, core) in cores.into_iter().enumerate() { 98 for core_name in cores.iter() {
76 let core_name = core["name"] 99 let key = format!("{}_{}", chip_name, core_name);
77 .as_str() 100 let value = vec![format!("stm32-metapac/{}_{}", chip_name, core_name)];
78 .unwrap_or_else(|| panic!("{}[cores][{}][name] is not a string", name, i));
79 let key = format!("{}_{}", name, core_name);
80 let value = vec![format!("stm32-metapac/{}_{}", name, core_name)];
81 result.insert(key, value); 101 result.insert(key, value);
82 } 102 }
83 } else { 103 } else {
84 let value = vec![format!("stm32-metapac/{}", &name)]; 104 let key = chip_name.to_string();
85 result.insert(name, value); 105 let value = vec![format!("stm32-metapac/{}", chip_name)];
106 result.insert(key, value);
107 }
108 }
109 result
110}
111
112/// Generate data needed in `../stm32-metapac/Cargo.toml`
113///
114/// Print errors to `stderr` when something is returned by the glob but is not in the returned
115/// [`Vec`]
116///
117/// # Panic
118/// Panics if a file contains yaml syntax errors or if a value does not have a consistent type
119pub fn stm32_metapac_needed_data(
120 names_and_cores: &[(String, Vec<String>)],
121) -> HashMap<String, Vec<String>> {
122 let mut result = HashMap::new();
123 for (chip_name, cores) in names_and_cores {
124 if cores.len() > 1 {
125 for core_name in cores {
126 let key = format!("{}_{}", chip_name, core_name);
127 result.insert(key, vec![]);
128 }
129 } else {
130 result.insert(chip_name.clone(), vec![]);
86 } 131 }
87 } 132 }
88 result 133 result
@@ -122,22 +167,22 @@ mod tests {
122 167
123 #[test] 168 #[test]
124 fn stm32f407vg_is_supported() { 169 fn stm32f407vg_is_supported() {
125 assert!(is_supported("STM32F407VG")) 170 assert!(is_supported("stm32f407vg"))
126 } 171 }
127 172
128 #[test] 173 #[test]
129 fn abcdef_is_not_supported() { 174 fn abcdef_is_not_supported() {
130 assert!(!is_supported("ABCDEF")) 175 assert!(!is_supported("abcdef"))
131 } 176 }
132 177
133 #[test] 178 #[test]
134 fn stm32f407vg_yaml_file_exists() { 179 #[ignore]
135 assert!(supported_chip_yaml_files_with_names() 180 fn stm32f407vg_yaml_file_exists_and_is_supported() {
181 assert!(chip_names_and_cores()
182 .as_slice()
183 .supported()
136 .into_iter() 184 .into_iter()
137 .any(|(path, name)| { 185 .any(|(name, _)| { name == "stm32f407vg" }))
138 name == "stm32f407vg"
139 && path.to_str() == Some("../stm32-data/data/chips/STM32F407VG.yaml")
140 }))
141 } 186 }
142 187
143 #[test] 188 #[test]
diff --git a/stm32-gen-features/src/main.rs b/stm32-gen-features/src/main.rs
index 9f1d8ef34..9edae4463 100644
--- a/stm32-gen-features/src/main.rs
+++ b/stm32-gen-features/src/main.rs
@@ -1,10 +1,20 @@
1use std::collections::HashMap; 1use std::collections::HashMap;
2 2
3use gen_features::{generate_cargo_toml_file, load_chip_list}; 3use gen_features::{
4 chip_names_and_cores, embassy_stm32_needed_data, generate_cargo_toml_file,
5 stm32_metapac_needed_data,
6};
4 7
5fn main() { 8fn main() {
6 let chip_list = load_chip_list(); 9 let names_and_cores = chip_names_and_cores();
7 update_cargo_file("../embassy-stm32/Cargo.toml", &chip_list); 10 update_cargo_file(
11 "../embassy-stm32/Cargo.toml",
12 &embassy_stm32_needed_data(&names_and_cores),
13 );
14 update_cargo_file(
15 "../stm32-metapac/Cargo.toml",
16 &stm32_metapac_needed_data(&names_and_cores),
17 );
8} 18}
9 19
10/// Update a Cargo.toml file 20/// Update a Cargo.toml file