neopdf/
parser.rs

1use neopdf::parser::{LhapdfSet, NeopdfSet};
2use pyo3::prelude::*;
3
4use super::gridpdf::PyGridArray;
5use super::metadata::PyMetaData;
6
7/// Python wrapper for the `LhapdfSet` struct.
8#[pyclass(name = "LhapdfSet")]
9pub struct PyLhapdfSet {
10    pub(crate) inner: LhapdfSet,
11}
12
13#[pymethods]
14impl PyLhapdfSet {
15    /// Create a new LhapdfSet instance for a given PDF set name.
16    #[new]
17    #[must_use]
18    pub fn new(pdf_name: &str) -> Self {
19        Self {
20            inner: LhapdfSet::new(pdf_name),
21        }
22    }
23
24    /// Get the metadata for this set.
25    #[must_use]
26    pub fn info(&self) -> PyMetaData {
27        PyMetaData {
28            meta: self.inner.info.clone(),
29        }
30    }
31
32    /// Get a member's metadata and grid array by index.
33    #[must_use]
34    pub fn member(&self, member: usize) -> (PyMetaData, PyGridArray) {
35        let (meta, gridarray) = self.inner.member(member);
36        let meta = PyMetaData { meta };
37        let gridarray = PyGridArray { gridarray };
38
39        (meta, gridarray)
40    }
41
42    /// Get all members' metadata and grid arrays.
43    #[must_use]
44    pub fn members(&self) -> Vec<(PyMetaData, PyGridArray)> {
45        // TODO: Use the parallelized `members` in the crate
46        let num_members = self.inner.members().len();
47        (0..num_members).map(|idx| self.member(idx)).collect()
48    }
49}
50
51/// Python wrapper for the `NeopdfSet` struct.
52#[pyclass(name = "NeopdfSet")]
53pub struct PyNeopdfSet {
54    pub(crate) inner: NeopdfSet,
55}
56
57#[pymethods]
58impl PyNeopdfSet {
59    /// Create a new NeopdfSet instance for a given PDF set name.
60    #[new]
61    #[must_use]
62    pub fn new(pdf_name: &str) -> Self {
63        Self {
64            inner: NeopdfSet::new(pdf_name),
65        }
66    }
67
68    /// Get the metadata for this set.
69    #[must_use]
70    pub fn info(&self) -> PyMetaData {
71        PyMetaData {
72            meta: self.inner.info.clone(),
73        }
74    }
75
76    /// Get a member's metadata and grid array by index.
77    #[must_use]
78    pub fn member(&self, member: usize) -> (PyMetaData, PyGridArray) {
79        let (meta, gridarray) = self.inner.member(member);
80        let meta = PyMetaData { meta };
81        let gridarray = PyGridArray { gridarray };
82
83        (meta, gridarray)
84    }
85}
86
87/// Registers the parser module with the parent Python module.
88///
89/// Adds the `parser` submodule to the parent Python module, exposing
90/// PDF set parser utilities to Python.
91///
92/// # Errors
93///
94/// Returns a `PyErr` if the submodule cannot be created or added, or
95/// if any class registration fails.
96pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
97    let m = PyModule::new(parent_module.py(), "parser")?;
98    m.setattr(
99        pyo3::intern!(m.py(), "__doc__"),
100        "PDF set parser utilities.",
101    )?;
102    pyo3::py_run!(
103        parent_module.py(),
104        m,
105        "import sys; sys.modules['neopdf.parser'] = m"
106    );
107    m.add_class::<PyLhapdfSet>()?;
108    m.add_class::<PyNeopdfSet>()?;
109    parent_module.add_submodule(&m)
110}