neopdf/manage.rs
1use neopdf::manage::{ManageData, PdfSetFormat};
2use pyo3::exceptions::PyRuntimeError;
3use pyo3::prelude::*;
4
5/// Python wrapper for the `PdfSetFormat` enum.
6#[pyclass(name = "PdfSetFormat")]
7#[derive(Clone)]
8pub enum PyPdfSetFormat {
9 /// LHAPDF format (standard PDF set format used by LHAPDF).
10 Lhapdf,
11 /// NeoPDF format (native format for this library).
12 Neopdf,
13}
14
15impl From<PyPdfSetFormat> for PdfSetFormat {
16 fn from(fmt: PyPdfSetFormat) -> Self {
17 match fmt {
18 PyPdfSetFormat::Lhapdf => Self::Lhapdf,
19 PyPdfSetFormat::Neopdf => Self::Neopdf,
20 }
21 }
22}
23
24/// Python wrapper for the `ManageData` struct.
25#[pyclass(name = "ManageData")]
26pub struct PyManageData {
27 pub(crate) inner: ManageData,
28}
29
30#[pymethods]
31impl PyManageData {
32 /// Create a new ManageData instance.
33 #[new]
34 #[must_use]
35 pub fn new(set_name: &str, format: PyPdfSetFormat) -> Self {
36 Self {
37 inner: ManageData::new(set_name, format.into()),
38 }
39 }
40
41 /// Download the PDF set and extract it into the designated path.
42 ///
43 /// Attempts to download the PDF set and extract it to the appropriate directory.
44 ///
45 /// # Returns
46 ///
47 /// Returns `Ok(())` if the download and extraction succeed, or a `PyRuntimeError`
48 /// if the operation fails.
49 ///
50 /// # Errors
51 ///
52 /// Returns a `PyRuntimeError` if the download or extraction fails due to network
53 /// issues, missing files, or I/O errors.
54 pub fn download_pdf(&self) -> PyResult<()> {
55 self.inner
56 .download_pdf()
57 .map_err(|e| PyRuntimeError::new_err(format!("{e}")))
58 }
59
60 /// Check that the PDF set is installed in the correct path.
61 ///
62 /// Returns `true` if the PDF set is installed, `false` otherwise.
63 #[must_use]
64 pub fn is_pdf_installed(&self) -> bool {
65 self.inner.is_pdf_installed()
66 }
67
68 /// Ensure that the PDF set is installed, otherwise download it.
69 ///
70 /// Ensures the PDF set is present; if not, attempts to download and install it.
71 ///
72 /// # Returns
73 ///
74 /// Returns `Ok(())` if the set is installed or successfully downloaded, or a
75 /// `PyRuntimeError` if the operation fails.
76 ///
77 /// # Errors
78 ///
79 /// Returns a `PyRuntimeError` if the download or installation fails due to network
80 /// issues, missing files, or I/O errors.
81 pub fn ensure_pdf_installed(&self) -> PyResult<()> {
82 self.inner
83 .ensure_pdf_installed()
84 .map_err(|e| PyRuntimeError::new_err(format!("{e}")))
85 }
86
87 /// Get the name of the PDF set.
88 #[must_use]
89 pub fn set_name(&self) -> &str {
90 self.inner.set_name()
91 }
92
93 /// Get the path where PDF sets are stored.
94 #[must_use]
95 pub fn data_path(&self) -> String {
96 self.inner.data_path().to_string_lossy().to_string()
97 }
98
99 /// Get the full path to this specific PDF set.
100 #[must_use]
101 pub fn set_path(&self) -> String {
102 self.inner.set_path().to_string_lossy().to_string()
103 }
104}
105
106/// Registers the manage module with the parent Python module.
107///
108/// Adds the `manage` submodule to the parent Python module, exposing PDF set
109/// management utilities to Python.
110///
111/// # Errors
112///
113/// Returns a `PyErr` if the submodule cannot be created or added, or if any
114/// class registration fails.
115pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
116 let m = PyModule::new(parent_module.py(), "manage")?;
117 m.setattr(
118 pyo3::intern!(m.py(), "__doc__"),
119 "PDF set management utilities.",
120 )?;
121 pyo3::py_run!(
122 parent_module.py(),
123 m,
124 "import sys; sys.modules['neopdf.manage'] = m"
125 );
126 m.add_class::<PyPdfSetFormat>()?;
127 m.add_class::<PyManageData>()?;
128 parent_module.add_submodule(&m)
129}