feagi_structures/genomic/
motor_cortical_unit.rs

1use crate::genomic::cortical_area::descriptors::{CorticalGroupIndex, CorticalUnitIndex};
2use crate::genomic::cortical_area::io_cortical_area_data_type::{
3    FrameChangeHandling, PercentageNeuronPositioning,
4};
5use crate::genomic::cortical_area::{CorticalAreaType, CorticalID, IOCorticalAreaDataFlag};
6use crate::genomic::sensory_cortical_unit::UnitTopology;
7use crate::motor_cortical_units;
8use paste;
9use std::collections::HashMap;
10use std::fmt::{Display, Formatter};
11
12macro_rules! define_motor_cortical_units_enum {
13    (
14        MotorCorticalUnit {
15            $(
16                $(#[doc = $doc:expr])?
17                $variant_name:ident => {
18                    friendly_name: $friendly_name:expr,
19                    snake_case_name: $snake_case_name:expr,
20                    accepted_wrapped_io_data_type: $accepted_wrapped_io_data_type:expr,
21                    cortical_id_unit_reference: $cortical_id_unit_reference:expr,
22                    number_cortical_areas: $number_cortical_areas:expr,
23                    cortical_type_parameters: {
24                        $($param_name:ident: $param_type:ty),* $(,)?
25                    },
26                    cortical_area_properties: {
27                        $($area_index:tt => ($cortical_area_type_expr:expr, relative_position: [$rel_x:expr, $rel_y:expr, $rel_z:expr], channel_dimensions_default: [$dim_default_x:expr, $dim_default_y:expr, $dim_default_z:expr], channel_dimensions_min: [$dim_min_x:expr, $dim_min_y:expr, $dim_min_z:expr], channel_dimensions_max: [$dim_max_x:expr, $dim_max_y:expr, $dim_max_z:expr])),* $(,)?
28                    }
29                }
30            ),* $(,)?
31        }
32    ) => {
33        #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, serde::Deserialize, serde::Serialize)]
34        pub enum MotorCorticalUnit {
35            $(
36                $(#[doc = $doc])?
37                $variant_name,
38            )*
39        }
40
41        impl MotorCorticalUnit {
42            $(
43                paste::paste! {
44                    #[doc = "Get cortical area types array for " $friendly_name "."]
45                    pub const fn [<get_cortical_area_types_array_for_ $snake_case_name >](
46                        $($param_name: $param_type),*) -> [CorticalAreaType; $number_cortical_areas] {
47                        [
48                            $(CorticalAreaType::BrainOutput($cortical_area_type_expr)),*
49                        ]
50                    }
51
52                    #[doc = "Get cortical IDs array for " $friendly_name "."]
53                    pub const fn [<get_cortical_ids_array_for_ $snake_case_name >](
54                        $($param_name: $param_type,)* cortical_group_index: CorticalGroupIndex) -> [CorticalID; $number_cortical_areas] {
55                        let cortical_unit_identifier: [u8; 3] = $cortical_id_unit_reference;
56                        [
57                            $(
58                                $cortical_area_type_expr .as_io_cortical_id(false, cortical_unit_identifier, CorticalUnitIndex::from($area_index), cortical_group_index)
59                            ),*
60                        ]
61                    }
62                }
63            )*
64
65            pub const fn get_snake_case_name(&self) -> &'static str {
66                match self {
67                    $(
68                        MotorCorticalUnit::$variant_name => $snake_case_name,
69                    )*
70                }
71            }
72
73            /// Parse a motor cortical unit from its snake_case name
74            ///
75            /// # Arguments
76            /// * `name` - The snake_case name (e.g., "positional_servo", "led_matrix")
77            ///
78            /// # Returns
79            /// * `Some(MotorCorticalUnit)` - If name matches a known type
80            /// * `None` - If name is not recognized
81            pub fn from_snake_case_name(name: &str) -> Option<MotorCorticalUnit> {
82                match name {
83                    $(
84                        $snake_case_name => Some(MotorCorticalUnit::$variant_name),
85                    )*
86                    _ => None,
87                }
88            }
89
90            /// Returns all available motor cortical unit types.
91            /// This is useful for enumerating all possible motor types in the system.
92            pub const fn list_all() -> &'static [MotorCorticalUnit] {
93                &[
94                    $(
95                        MotorCorticalUnit::$variant_name,
96                    )*
97                ]
98            }
99
100            /// Returns the friendly (human-readable) name for this motor cortical unit type.
101            pub const fn get_friendly_name(&self) -> &'static str {
102                match self {
103                    $(
104                        MotorCorticalUnit::$variant_name => $friendly_name,
105                    )*
106                }
107            }
108
109            /// Returns the 3-byte cortical ID unit reference for this type.
110            pub const fn get_cortical_id_unit_reference(&self) -> [u8; 3] {
111                match self {
112                    $(
113                        MotorCorticalUnit::$variant_name => $cortical_id_unit_reference,
114                    )*
115                }
116            }
117
118            /// Returns the number of cortical areas this type creates.
119            pub const fn get_number_cortical_areas(&self) -> usize {
120                match self {
121                    $(
122                        MotorCorticalUnit::$variant_name => $number_cortical_areas,
123                    )*
124                }
125            }
126
127            /// Returns the default topology for all units of this cortical type.
128            pub fn get_unit_default_topology(&self) -> HashMap<usize, UnitTopology> {
129                match self {
130                    $(
131                        MotorCorticalUnit::$variant_name => {
132                            let mut topology = HashMap::new();
133                            $(
134                                topology.insert(
135                                    $area_index,
136                                    UnitTopology {
137                                        relative_position: [$rel_x, $rel_y, $rel_z],
138                                        channel_dimensions_default: [$dim_default_x, $dim_default_y, $dim_default_z],
139                                        channel_dimensions_min: [$dim_min_x, $dim_min_y, $dim_min_z],
140                                        channel_dimensions_max: [$dim_max_x, $dim_max_y, $dim_max_z],
141                                    }
142                                );
143                            )*
144                            topology
145                        }
146                    )*
147                }
148            }
149
150        }
151
152        impl Display for MotorCorticalUnit {
153            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
154                match self {
155                    $(
156                        MotorCorticalUnit::$variant_name => write!(f, $friendly_name),
157                    )*
158                }
159            }
160        }
161    };
162
163}
164// Generate the MotorCorticalUnit enum and all helper methods from the template
165motor_cortical_units!(define_motor_cortical_units_enum);