1use std::collections::HashSet;
5use std::convert::TryFrom;
6use std::fmt::Debug;
7
8pub trait StructureIdentifier: Copy + Clone + Debug + TryFrom<isize> + Into<isize> {
10 fn allowed_values(no_catchall: bool) -> Option<HashSet<isize>>;
15
16 fn as_str(&self) -> Option<&'static str>;
18}
19
20#[macro_export]
34macro_rules! structure_mapping {
35 ( $id:ident $(, $val:literal = $name:ident $desc:expr )* $(,)?) => {
36 #[derive(Copy, Clone, Debug)]
37 #[allow(missing_docs)]
38 pub enum $id {
39 $( $name, )+
40 }
41
42 impl TryFrom<isize> for $id {
43 type Error = isize;
44
45 fn try_from(val: isize) -> Result<Self, Self::Error> {
46 match val {
47 $( $val => Ok(Self::$name), )*
48 value => Err(value),
49 }
50 }
51 }
52
53 impl From<$id> for isize {
54 fn from(val: $id) -> Self {
55 match val {
56 $( $id::$name => $val, )*
57 }
58 }
59 }
60
61 impl StructureIdentifier for $id {
62 fn allowed_values(_no_catchall: bool) -> Option<HashSet<isize>> {
63 Some(vec![$( $val, )*].into_iter().collect())
64 }
65
66 fn as_str(&self) -> Option<&'static str> {
67 match self {
68 $( Self::$name => Some($desc), )*
69 }
70 }
71 }
72
73 };
74 ( $id:ident $(, $val:literal = $name:ident $desc:expr )*, $othername:ident $(,)?) => {
75 #[derive(Copy, Clone, Debug)]
76 #[allow(missing_docs)]
77 pub enum $id {
78 $( $name, )*
79 $othername(isize),
80 }
81
82 impl From<isize> for $id {
83 fn from(val: isize) -> Self {
84 match val {
85 $( $val => Self::$name, )*
86 x => Self::$othername(x),
87 }
88 }
89 }
90
91 impl From<$id> for isize {
92 fn from(val: $id) -> Self {
93 match val {
94 $( $id::$name => $val, )*
95 $id::$othername(x) => x,
96 }
97 }
98 }
99
100 impl StructureIdentifier for $id {
101 fn allowed_values(no_catchall: bool) -> Option<HashSet<isize>> {
102 if no_catchall {
103 Some(vec![$( $val, )*].into_iter().collect())
104 } else {
105 None
106 }
107 }
108
109 fn as_str(&self) -> Option<&'static str> {
110 match self {
111 $( Self::$name => Some($desc), )*
112 Self::$othername(_) => None,
113 }
114 }
115 }
116
117 };
118}
119
120#[macro_export]
125macro_rules! neuromorpho_ext {
126 ( $id:ident $(, $val:literal = $name:ident $desc:expr )* $(,)?) => {
127 structure_mapping!(
128 $id,
129 -1 = Root "root",
130 0 = Undefined "undefined",
131 1 = Soma "soma",
132 2 = Axon "axon",
133 3 = BasalDendrite "basal dendrite",
134 4 = ApicalDendrite "apical dendrite",
135 $($val = $name $desc, )*
136 );
137 };
138 ( $id:ident $(, $val:literal = $name:ident $desc:expr )*, $othername:ident $(,)?) => {
139 structure_mapping!(
140 $id,
141 -1 = Root "root",
142 0 = Undefined "undefined",
143 1 = Soma "soma",
144 2 = Axon "axon",
145 3 = BasalDendrite "basal dendrite",
146 4 = ApicalDendrite "apical dendrite",
147 $($val = $name $desc, )*
148 $othername,
149 );
150 };
151}
152
153neuromorpho_ext!(NeuromorphoStructure, Custom);
154neuromorpho_ext!(CnicStructure, 5 = ForkPoint "fork point", 6 = EndPoint "end point", 7 = Custom "custom");
155neuromorpho_ext!(
156 NavisStructure,
157 5 = ForkPoint "fork point",
158 6 = EndPoint "end point",
159 7 = Presynapse "presynapse",
160 8 = Postsynapse "postsynapse",
161 9 = PreAndPostsynapse "pre and postsynapse",
162 Custom,
163);
164neuromorpho_ext!(VnedStructure, 10 = SomaRelated "soma related", Custom);
165
166structure_mapping!(GulyasStructure, IsoDiameterStructure);
167structure_mapping!(AnyStructure, Any);