#[copper_runtime]
Expand description
Adds #[copper_runtime(config = “path”, sim_mode = false/true)] to your application struct to generate the runtime. +
#[copper_runtime]
Expand description
Adds #[copper_runtime(config = “path”, sim_mode = false/true)] to your application struct to generate the runtime. if sim_mode is ommited, it is set to false. This will add a “runtime” field to your struct and implement the “new” and “run” methods.
Macros§
- Generates the CopperList content type from a config. +
cu29_derive - Rust Macros§
- Generates the CopperList content type from a config. gen_cumsgs!(“path/to/config.toml”) It will create a new type called CuMsgs you can pass to the log reader for decoding:
Attribute Macros§
- Adds #[copper_runtime(config = “path”, sim_mode = false/true)] to your application struct to generate the runtime. if sim_mode is ommited, it is set to false. diff --git a/cu29_derive/macro.gen_cumsgs.html b/cu29_derive/macro.gen_cumsgs.html index 0ea292cf7..5ac9e4c1f 100644 --- a/cu29_derive/macro.gen_cumsgs.html +++ b/cu29_derive/macro.gen_cumsgs.html @@ -1,4 +1,4 @@ -
gen_cumsgs in cu29_derive - Rust gen_cumsgs!() { /* proc-macro */ }
Expand description
Generates the CopperList content type from a config. +
gen_cumsgs in cu29_derive - Rust \ No newline at end of file diff --git a/src/cu29_derive/lib.rs.html b/src/cu29_derive/lib.rs.html index 26285e190..832207569 100644 --- a/src/cu29_derive/lib.rs.html +++ b/src/cu29_derive/lib.rs.html @@ -1211,10 +1211,58 @@ 1210 1211 1212 -1213gen_cumsgs!() { /* proc-macro */ }
Expand description
Generates the CopperList content type from a config. gen_cumsgs!(“path/to/config.toml”) It will create a new type called CuMsgs you can pass to the log reader for decoding:
extern crate proc_macro; +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261
extern crate proc_macro; use proc_macro::TokenStream; -use quote::quote; +use quote::{format_ident, quote}; use std::fs::read_to_string; use syn::meta::parser; use syn::Fields::{Named, Unnamed}; @@ -1255,6 +1303,13 @@ let runtime_plan: CuExecutionLoop = compute_runtime_plan(&cuconfig).expect("Could not compute runtime plan"); + // Give a name compatible with a struct to match the task ids to their output in the CuMsgs tuple. + let all_tasks_member_ids: Vec<String> = cuconfig + .get_all_nodes() + .iter() + .map(|(_, node)| utils::config_id_to_struct_member(node.get_id().as_str())) + .collect(); + // All accesses are linear on the culist but the id of the tasks is random (determined by the Ron declaration order). // This records the task ids in call order. let taskid_order: Vec<usize> = runtime_plan @@ -1266,7 +1321,16 @@ }) .collect(); - let support = gen_culist_support(&runtime_plan, &taskid_order); + #[cfg(feature = "macro_debug")] + eprintln!( + "[The CuMsgs matching tasks ids are {:?}]", + taskid_order + .iter() + .map(|i| all_tasks_member_ids[*i].clone()) + .collect::<Vec<_>>() + ); + + let support = gen_culist_support(&runtime_plan, &taskid_order, &all_tasks_member_ids); let with_uses = quote! { mod cumsgs { @@ -1290,6 +1354,7 @@ fn gen_culist_support( runtime_plan: &CuExecutionLoop, taskid_call_order: &[usize], + all_tasks_as_struct_member_name: &Vec<String>, ) -> proc_macro2::TokenStream { #[cfg(feature = "macro_debug")] eprintln!("[Extract msgs types]"); @@ -1320,6 +1385,19 @@ } }; + let methods = itertools::multizip((all_tasks_as_struct_member_name, taskid_call_order)).map( + |(name, output_position)| { + let fn_name = format_ident!("get_{}_output", name); + let payload_type = all_msgs_types_in_culist_order[*output_position].clone(); + let index = syn::Index::from(*output_position); + quote! { + pub fn #fn_name(&self) -> &_CuMsg<#payload_type> { + &self.0.#index + } + } + }, + ); + // This generates a way to get the metadata of every single message of a culist at low cost quote! { #collect_metadata_function @@ -1327,6 +1405,18 @@ pub struct CuMsgs(#msgs_types_tuple); pub type CuList = _CopperList<CuMsgs>; + impl CuMsgs { + #(#methods)* + + fn get_tuple(&self) -> &#msgs_types_tuple { + &self.0 + } + + fn get_tuple_mut(&mut self) -> &mut #msgs_types_tuple { + &mut self.0 + } + } + // Adds the bincode support for the copper list tuple #msgs_types_tuple_encode #msgs_types_tuple_decode @@ -1999,10 +2089,16 @@ #[cfg(feature = "macro_debug")] eprintln!("[Culist access order: {:?}]", taskid_call_order); + // Give a name compatible with a struct to match the task ids to their output in the CuMsgs tuple. + let all_tasks_member_ids: Vec<String> = all_tasks_ids + .iter() + .map(|name| utils::config_id_to_struct_member(name.as_str())) + .collect(); + #[cfg(feature = "macro_debug")] eprintln!("[build the copperlist support]"); let culist_support: proc_macro2::TokenStream = - gen_culist_support(&runtime_plan, &taskid_call_order); + gen_culist_support(&runtime_plan, &taskid_call_order, &all_tasks_member_ids); #[cfg(feature = "macro_debug")] eprintln!("[build the sim support]"); diff --git a/src/cu29_derive/utils.rs.html b/src/cu29_derive/utils.rs.html index e99837115..b069b8dac 100644 --- a/src/cu29_derive/utils.rs.html +++ b/src/cu29_derive/utils.rs.html @@ -107,7 +107,44 @@ 106 107 108 -109
use convert_case::{Case, Casing}; +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
use convert_case::{Case, Casing}; use std::path::PathBuf; use walkdir::WalkDir; @@ -131,6 +168,26 @@ candidate } +/// Same as config_id_to_enum but for a struct member name +pub(crate) fn config_id_to_struct_member(id: &str) -> String { + let mut candidate = id + .chars() + .map(|c| if c.is_alphanumeric() { c } else { '_' }) + .collect::<String>(); + + candidate = candidate.to_case(Case::Snake); + + if candidate + .chars() + .next() + .map_or(false, |c| c.is_ascii_digit()) + { + candidate.insert(0, '_'); + } + + candidate +} + // Lifted this HORROR but it works. pub fn caller_crate_root() -> PathBuf { let crate_name = @@ -215,5 +272,22 @@ ); }) } + + #[test] + fn test_identifier_to_struct_member() { + assert_eq!(crate::utils::config_id_to_struct_member("toto"), "toto"); + assert_eq!(crate::utils::config_id_to_struct_member("#id"), "id"); + assert_eq!( + crate::utils::config_id_to_struct_member("!!something"), + "something" + ); + assert_eq!(crate::utils::config_id_to_struct_member("hey?"), "hey"); + assert_eq!(crate::utils::config_id_to_struct_member("é"), "é"); + assert_eq!(crate::utils::config_id_to_struct_member("T"), "t"); + assert_eq!( + crate::utils::config_id_to_struct_member("Test_Dunder"), + "test_dunder" + ); + } }