pyo3_stub_gen/
pyproject.rs

1//! `pyproject.toml` parser for reading `[tool.maturin]` configuration.
2//!
3//! ```
4//! use pyo3_stub_gen::pyproject::PyProject;
5//! use std::path::Path;
6//!
7//! let root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap();
8//! let pyproject = PyProject::parse_toml(
9//!     root.join("examples/mixed/pyproject.toml")
10//! ).unwrap();
11//! ```
12
13use anyhow::{bail, Result};
14use serde::{Deserialize, Serialize};
15use std::{fs, path::*};
16
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub struct PyProject {
19    pub project: Project,
20    pub tool: Option<Tool>,
21
22    #[serde(skip)]
23    toml_path: PathBuf,
24}
25
26impl PyProject {
27    pub fn parse_toml(path: impl AsRef<Path>) -> Result<Self> {
28        let path = path.as_ref();
29        if path.file_name() != Some("pyproject.toml".as_ref()) {
30            bail!("{} is not a pyproject.toml", path.display())
31        }
32        let mut out: PyProject = toml::de::from_str(&fs::read_to_string(path)?)?;
33        out.toml_path = path.to_path_buf();
34        Ok(out)
35    }
36
37    pub fn module_name(&self) -> &str {
38        if let Some(tool) = &self.tool {
39            if let Some(maturin) = &tool.maturin {
40                if let Some(module_name) = &maturin.module_name {
41                    return module_name;
42                }
43            }
44        }
45        &self.project.name
46    }
47
48    /// Return `tool.maturin.python_source` if it exists, which means the project is a mixed Rust/Python project.
49    pub fn python_source(&self) -> Option<PathBuf> {
50        if let Some(tool) = &self.tool {
51            if let Some(maturin) = &tool.maturin {
52                if let Some(python_source) = &maturin.python_source {
53                    if let Some(base) = self.toml_path.parent() {
54                        return Some(base.join(python_source));
55                    } else {
56                        return Some(PathBuf::from(python_source));
57                    }
58                }
59            }
60        }
61        None
62    }
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
66pub struct Project {
67    pub name: String,
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub struct Tool {
72    pub maturin: Option<Maturin>,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
76pub struct Maturin {
77    #[serde(rename = "python-source")]
78    pub python_source: Option<String>,
79    #[serde(rename = "module-name")]
80    pub module_name: Option<String>,
81}