rtic_macros/syntax/
accessors.rs

1use syn::Ident;
2
3use crate::syntax::{
4    analyze::Priority,
5    ast::{Access, App, Local, TaskLocal},
6};
7
8impl App {
9    pub(crate) fn shared_resource_accesses(
10        &self,
11    ) -> impl Iterator<Item = (Option<Priority>, &Ident, Access)> {
12        self.idle
13            .iter()
14            .flat_map(|idle| {
15                idle.args
16                    .shared_resources
17                    .iter()
18                    .map(move |(name, access)| (Some(0), name, *access))
19            })
20            .chain(self.hardware_tasks.values().flat_map(|task| {
21                task.args
22                    .shared_resources
23                    .iter()
24                    .map(move |(name, access)| (Some(task.args.priority), name, *access))
25            }))
26            .chain(self.software_tasks.values().flat_map(|task| {
27                task.args
28                    .shared_resources
29                    .iter()
30                    .map(move |(name, access)| (Some(task.args.priority), name, *access))
31            }))
32    }
33
34    fn is_external(task_local: &TaskLocal) -> bool {
35        matches!(task_local, TaskLocal::External)
36    }
37
38    pub(crate) fn local_resource_accesses(&self) -> impl Iterator<Item = &Ident> {
39        self.init
40            .args
41            .local_resources
42            .iter()
43            .filter(|(_, task_local)| Self::is_external(task_local)) // Only check the resources declared in `#[local]`
44            .map(move |(name, _)| name)
45            .chain(self.idle.iter().flat_map(|idle| {
46                idle.args
47                    .local_resources
48                    .iter()
49                    .filter(|(_, task_local)| Self::is_external(task_local)) // Only check the resources declared in `#[local]`
50                    .map(move |(name, _)| name)
51            }))
52            .chain(self.hardware_tasks.values().flat_map(|task| {
53                task.args
54                    .local_resources
55                    .iter()
56                    .filter(|(_, task_local)| Self::is_external(task_local)) // Only check the resources declared in `#[local]`
57                    .map(move |(name, _)| name)
58            }))
59            .chain(self.software_tasks.values().flat_map(|task| {
60                task.args
61                    .local_resources
62                    .iter()
63                    .filter(|(_, task_local)| Self::is_external(task_local)) // Only check the resources declared in `#[local]`
64                    .map(move |(name, _)| name)
65            }))
66    }
67
68    fn get_declared_local(tl: &TaskLocal) -> Option<&Local> {
69        match tl {
70            TaskLocal::External => None,
71            TaskLocal::Declared(l) => Some(l),
72        }
73    }
74
75    /// Get all declared local resources, i.e. `local = [NAME: TYPE = EXPR]`.
76    ///
77    /// Returns a vector of (task name, resource name, `Local` struct)
78    pub fn declared_local_resources(&self) -> Vec<(&Ident, &Ident, &Local)> {
79        self.init
80            .args
81            .local_resources
82            .iter()
83            .filter_map(move |(name, tl)| {
84                Self::get_declared_local(tl).map(|l| (&self.init.name, name, l))
85            })
86            .chain(self.idle.iter().flat_map(|idle| {
87                idle.args
88                    .local_resources
89                    .iter()
90                    .filter_map(move |(name, tl)| {
91                        Self::get_declared_local(tl)
92                            .map(|l| (&self.idle.as_ref().unwrap().name, name, l))
93                    })
94            }))
95            .chain(self.hardware_tasks.iter().flat_map(|(task_name, task)| {
96                task.args
97                    .local_resources
98                    .iter()
99                    .filter_map(move |(name, tl)| {
100                        Self::get_declared_local(tl).map(|l| (task_name, name, l))
101                    })
102            }))
103            .chain(self.software_tasks.iter().flat_map(|(task_name, task)| {
104                task.args
105                    .local_resources
106                    .iter()
107                    .filter_map(move |(name, tl)| {
108                        Self::get_declared_local(tl).map(|l| (task_name, name, l))
109                    })
110            }))
111            .collect()
112    }
113}