pyo3_stub_gen/
pyproject.rs1use 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 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 pub fn stub_gen_config(&self) -> StubGenConfig {
67 self.tool
68 .as_ref()
69 .and_then(|t| t.pyo3_stub_gen.clone())
70 .unwrap_or_default()
71 }
72}
73
74#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
75pub struct Project {
76 pub name: String,
77}
78
79#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
80pub struct Tool {
81 pub maturin: Option<Maturin>,
82 #[serde(rename = "pyo3-stub-gen")]
83 pub pyo3_stub_gen: Option<StubGenConfig>,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87pub struct Maturin {
88 #[serde(rename = "python-source")]
89 pub python_source: Option<String>,
90 #[serde(rename = "module-name")]
91 pub module_name: Option<String>,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
99#[non_exhaustive]
100pub struct StubGenConfig {
101 #[serde(rename = "use-type-statement", default)]
104 pub use_type_statement: bool,
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_stub_gen_config_true() {
113 let toml_str = r#"
114 [project]
115 name = "test"
116
117 [tool.pyo3-stub-gen]
118 use-type-statement = true
119 "#;
120 let pyproject: PyProject = toml::from_str(toml_str).unwrap();
121 assert!(pyproject.stub_gen_config().use_type_statement);
122 }
123
124 #[test]
125 fn test_stub_gen_config_false() {
126 let toml_str = r#"
127 [project]
128 name = "test"
129
130 [tool.pyo3-stub-gen]
131 use-type-statement = false
132 "#;
133 let pyproject: PyProject = toml::from_str(toml_str).unwrap();
134 assert!(!pyproject.stub_gen_config().use_type_statement);
135 }
136
137 #[test]
138 fn test_stub_gen_config_default() {
139 let toml_str = r#"
140 [project]
141 name = "test"
142 "#;
143 let pyproject: PyProject = toml::from_str(toml_str).unwrap();
144 assert!(!pyproject.stub_gen_config().use_type_statement);
145 }
146
147 #[test]
148 fn test_stub_gen_config_empty_section() {
149 let toml_str = r#"
150 [project]
151 name = "test"
152
153 [tool.pyo3-stub-gen]
154 "#;
155 let pyproject: PyProject = toml::from_str(toml_str).unwrap();
156 assert!(!pyproject.stub_gen_config().use_type_statement);
157 }
158}