1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! Declarative macro for generating Python binding functions
//!
//! This macro eliminates ~200 lines of duplicated code by providing a single
//! declaration point for microformat extractor Python bindings.
//!
//! # Usage
//!
//! ```rust
//! py_extractor_binding!(extract_hcard, hcard, HCard);
//! py_extractor_binding!(extract_hentry, hentry, HEntry);
//! ```
//!
//! # What It Generates
//!
//! For each invocation, the macro generates a complete PyO3 function with:
//! - Proper `#[pyfunction]` annotation
//! - `#[pyo3(signature = (html, base_url=None))]` for optional parameters
//! - GIL acquisition via `Python::with_gil`
//! - Error conversion to PyValueError
//! - Automatic conversion to Python objects via `.to_py_dict()`
//!
//! # Example Expansion
//!
//! ```rust
//! py_extractor_binding!(extract_hcard, hcard, HCard);
//! ```
//!
//! Expands to:
//!
//! ```rust
//! /// Extract h-card microformat data
//! #[pyfunction]
//! #[pyo3(signature = (html, base_url=None))]
//! fn extract_hcard(html: &str, base_url: Option<&str>) -> PyResult<Vec<PyObject>> {
//! Python::with_gil(|py| {
//! let items = extractors::microformats::hcard::extract(html, base_url)
//! .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e.to_string()))?;
//!
//! Ok(items.iter().map(|item| item.to_py_dict(py).into()).collect())
//! })
//! }
//! ```
/// Generate a Python binding function for a microformat extractor
///
/// # Parameters
///
/// - `$func_name`: The name of the Python function (e.g., `extract_hcard`)
/// - `$module`: The extractor module name (e.g., `hcard`)
/// - `$type_name`: The Rust type name (e.g., `HCard`) - currently unused but reserved for future enhancements
///
/// # Examples
///
/// ```rust
/// // Generate binding for h-card extractor
/// py_extractor_binding!(extract_hcard, hcard, HCard);
///
/// // Generate binding for h-entry extractor
/// py_extractor_binding!(extract_hentry, hentry, HEntry);
///
/// // Generate binding for h-event extractor
/// py_extractor_binding!(extract_hevent, hevent, HEvent);
/// ```