use proc_macro2::{Span, TokenStream};
use quote::quote;
use rtic_syntax::{ast::App, Context};
use syn::{Ident, LitInt, PatType};
const RTIC_INTERNAL: &str = "__rtic_internal";
pub fn mark_internal_name(name: &str) -> Ident {
Ident::new(&format!("{}_{}", RTIC_INTERNAL, name), Span::call_site())
}
pub fn task_input_queue_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_input_queue", task.to_string()))
}
pub fn run_queue_ident(priority: u8) -> Ident {
mark_internal_name(&format!("P{}_run_queue", priority))
}
pub fn thread_init_barrier() -> Ident {
mark_internal_name(&format!("thread_init_barrier"))
}
pub fn thread_ident(priority: u8) -> Ident {
mark_internal_name(&format!("thread_P{}", priority))
}
pub fn thread_name(priority: u8) -> String {
format!("thd_P{}", priority)
}
pub fn spawn_enum_ident(priority: u8) -> Ident {
Ident::new(&format!("P{}_tasks", priority), Span::call_site())
}
pub fn internal_task_context_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_context", task.to_string()))
}
pub fn internal_task_spawn_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_spawn", task.to_string()))
}
pub fn internal_task_spawn_at_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_spawn_at", task.to_string()))
}
pub fn internal_task_spawn_after_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_spawn_after", task.to_string()))
}
pub fn shared_resources_ident(ctxt: Context, app: &App) -> Ident {
let mut s = match ctxt {
Context::Init => app.init.name.to_string(),
Context::Idle => app.idle.as_ref().unwrap().name.to_string(),
Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
};
s.push_str("SharedResources");
mark_internal_name(&s)
}
pub fn local_resources_ident(ctxt: Context, app: &App) -> Ident {
let mut s = match ctxt {
Context::Init => app.init.name.to_string(),
Context::Idle => app.idle.as_ref().unwrap().name.to_string(),
Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
};
s.push_str("LocalResources");
mark_internal_name(&s)
}
pub fn capacity_literal(capacity: usize) -> LitInt {
LitInt::new(&capacity.to_string(), Span::call_site())
}
pub fn regroup_inputs(
inputs: &[PatType],
) -> (
// args e.g. &[`_0`], &[`_0: i32`, `_1: i64`]
Vec<TokenStream>,
// tupled e.g. `_0`, `(_0, _1)`
TokenStream,
// untupled e.g. &[`_0`], &[`_0`, `_1`]
Vec<TokenStream>,
// ty e.g. `Foo`, `(i32, i64)`
TokenStream,
) {
if inputs.len() == 1 {
let ty = &inputs[0].ty;
(
vec![quote!(_0: #ty)],
quote!(_0),
vec![quote!(_0)],
quote!(#ty),
)
} else {
let mut args = vec![];
let mut pats = vec![];
let mut tys = vec![];
for (i, input) in inputs.iter().enumerate() {
let i = Ident::new(&format!("_{}", i), Span::call_site());
let ty = &input.ty;
args.push(quote!(#i: #ty));
pats.push(quote!(#i));
tys.push(quote!(#ty));
}
let tupled = {
let pats = pats.clone();
quote!((#(#pats,)*))
};
let ty = quote!((#(#tys,)*));
(args, tupled, pats, ty)
}
}
pub fn get_task_name(ctxt: Context, app: &App) -> Ident {
let s = match ctxt {
Context::Init => app.init.name.to_string(),
Context::Idle => app.idle.as_ref().unwrap().name.to_string(),
Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
};
Ident::new(&s, Span::call_site())
}
pub fn static_shared_resource_ident(name: &Ident) -> Ident {
mark_internal_name(&format!("shared_resource_{}", name.to_string()))
}
pub fn static_local_resource_ident(name: &Ident) -> Ident {
mark_internal_name(&format!("local_resource_{}", name.to_string()))
}
pub fn declared_static_local_resource_ident(name: &Ident, task_name: &Ident) -> Ident {
mark_internal_name(&format!(
"local_{}_{}",
task_name.to_string(),
name.to_string()
))
}