Attribute macro for struct sequences. Usage: ```ignore #[pystruct_sequence_data] struct StructTimeData { ... } #[pystruct_sequence(name = "struct_time", module = "time", data = "StructTimeData")] struct PyStructTime; ```
(
attr: PunctuatedNestedMeta,
item: Item,
)
| 523 | /// struct PyStructTime; |
| 524 | /// ``` |
| 525 | pub(crate) fn impl_pystruct_sequence( |
| 526 | attr: PunctuatedNestedMeta, |
| 527 | item: Item, |
| 528 | ) -> Result<TokenStream> { |
| 529 | let Item::Struct(struct_item) = item else { |
| 530 | bail_span!(item, "#[pystruct_sequence] can only be applied to a struct"); |
| 531 | }; |
| 532 | |
| 533 | let ident = struct_item.ident.clone(); |
| 534 | let fake_ident = Ident::new("pystruct_sequence", ident.span()); |
| 535 | let meta = PyStructSequenceMeta::from_nested(ident, fake_ident, attr.into_iter())?; |
| 536 | |
| 537 | let pytype_ident = struct_item.ident.clone(); |
| 538 | let pytype_vis = struct_item.vis.clone(); |
| 539 | let data_ident = meta.data_type()?; |
| 540 | |
| 541 | let class_name = meta.class_name()?.ok_or_else(|| { |
| 542 | syn::Error::new_spanned( |
| 543 | &struct_item.ident, |
| 544 | "#[pystruct_sequence] requires name parameter", |
| 545 | ) |
| 546 | })?; |
| 547 | let module_name = meta.module()?; |
| 548 | |
| 549 | // Module name handling |
| 550 | let module_name_tokens = match &module_name { |
| 551 | Some(m) => quote!(Some(#m)), |
| 552 | None => quote!(None), |
| 553 | }; |
| 554 | |
| 555 | let module_class_name = if let Some(ref m) = module_name { |
| 556 | format!("{}.{}", m, class_name) |
| 557 | } else { |
| 558 | class_name.clone() |
| 559 | }; |
| 560 | |
| 561 | let output = quote! { |
| 562 | // The Python type struct - newtype wrapping PyTuple |
| 563 | #[derive(Debug)] |
| 564 | #[repr(transparent)] |
| 565 | #pytype_vis struct #pytype_ident(pub ::rustpython_vm::builtins::PyTuple); |
| 566 | |
| 567 | // PyClassDef for Python type |
| 568 | impl ::rustpython_vm::class::PyClassDef for #pytype_ident { |
| 569 | const NAME: &'static str = #class_name; |
| 570 | const MODULE_NAME: Option<&'static str> = #module_name_tokens; |
| 571 | const TP_NAME: &'static str = #module_class_name; |
| 572 | const DOC: Option<&'static str> = None; |
| 573 | const BASICSIZE: usize = 0; |
| 574 | const UNHASHABLE: bool = false; |
| 575 | |
| 576 | type Base = ::rustpython_vm::builtins::PyTuple; |
| 577 | } |
| 578 | |
| 579 | // StaticType for Python type |
| 580 | impl ::rustpython_vm::class::StaticType for #pytype_ident { |
| 581 | fn static_cell() -> &'static ::rustpython_vm::common::static_cell::StaticCell<::rustpython_vm::builtins::PyTypeRef> { |
| 582 | ::rustpython_vm::common::static_cell! { |
no test coverage detected