| 188 | } |
| 189 | |
| 190 | pub fn _optional_path(&self, key: &str) -> Result<Option<syn::Path>> { |
| 191 | let value = if let Some((_, meta)) = self.meta_map.get(key) { |
| 192 | let Meta::NameValue(syn::MetaNameValue { value, .. }) = meta else { |
| 193 | bail_span!( |
| 194 | meta, |
| 195 | "#[{}({} = ...)] must be a name-value pair", |
| 196 | self.meta_name(), |
| 197 | key |
| 198 | ) |
| 199 | }; |
| 200 | |
| 201 | // Try to parse as a Path (identifier or path like Foo or foo::Bar) |
| 202 | match syn::parse2::<syn::Path>(value.to_token_stream()) { |
| 203 | Ok(path) => Some(path), |
| 204 | Err(_) => { |
| 205 | bail_span!( |
| 206 | value, |
| 207 | "#[{}({} = ...)] must be a valid type path (e.g., PyBaseException)", |
| 208 | self.meta_name(), |
| 209 | key |
| 210 | ) |
| 211 | } |
| 212 | } |
| 213 | } else { |
| 214 | None |
| 215 | }; |
| 216 | Ok(value) |
| 217 | } |
| 218 | |
| 219 | pub fn _has_key(&self, key: &str) -> Result<bool> { |
| 220 | Ok(matches!(self.meta_map.get(key), Some((_, _)))) |