From f2f8c9c7ce92a4f6a8eb1de29a330bfd68337ce1 Mon Sep 17 00:00:00 2001 From: Andrej Orsula Date: Fri, 8 Mar 2024 23:52:07 +0100 Subject: [PATCH] Add examples Signed-off-by: Andrej Orsula --- Cargo.lock | 9 +++++++++ Cargo.toml | 8 ++++++++ examples/Cargo.toml | 31 +++++++++++++++++++++++++++++++ examples/build.rs | 8 ++++++++ examples/math.rs | 26 ++++++++++++++++++++++++++ examples/os_sys.rs | 34 ++++++++++++++++++++++++++++++++++ examples/pygal.rs | 33 +++++++++++++++++++++++++++++++++ examples/random.rs | 22 ++++++++++++++++++++++ 8 files changed, 171 insertions(+) create mode 100644 examples/Cargo.toml create mode 100644 examples/build.rs create mode 100644 examples/math.rs create mode 100644 examples/os_sys.rs create mode 100644 examples/pygal.rs create mode 100644 examples/random.rs diff --git a/Cargo.lock b/Cargo.lock index b9c0846..1ccabd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,6 +279,14 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "examples" +version = "0.4.0" +dependencies = [ + "pyo3", + "pyo3_bindgen", +] + [[package]] name = "float-cmp" version = "0.9.0" @@ -569,6 +577,7 @@ dependencies = [ name = "pyo3_bindgen" version = "0.4.0" dependencies = [ + "pyo3", "pyo3_bindgen_engine", "pyo3_bindgen_macros", ] diff --git a/Cargo.toml b/Cargo.toml index 1b0fd04..8b2d55f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [workspace] members = [ + # Examples of usage + "examples", # Public API "pyo3_bindgen", # CLI tool @@ -9,6 +11,12 @@ members = [ # Procedural macros "pyo3_bindgen_macros", ] +default-members = [ + "pyo3_bindgen", + "pyo3_bindgen_cli", + "pyo3_bindgen_engine", + "pyo3_bindgen_macros", +] resolver = "2" [workspace.package] diff --git a/examples/Cargo.toml b/examples/Cargo.toml new file mode 100644 index 0000000..57e9f38 --- /dev/null +++ b/examples/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "examples" +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +version.workspace = true +publish = false + +[dependencies] +pyo3 = { workspace = true, features = ["auto-initialize"] } +pyo3_bindgen = { workspace = true } + +[build-dependencies] +pyo3_bindgen = { workspace = true } + +[[example]] +name = "math" +path = "math.rs" + +[[example]] +name = "os_sys" +path = "os_sys.rs" + +[[example]] +name = "pygal" +path = "pygal.rs" + +[[example]] +name = "random" +path = "random.rs" diff --git a/examples/build.rs b/examples/build.rs new file mode 100644 index 0000000..d7cee3f --- /dev/null +++ b/examples/build.rs @@ -0,0 +1,8 @@ +use pyo3_bindgen::Codegen; + +fn main() -> Result<(), Box> { + Codegen::default() + .module_names(["os", "posixpath", "sys"])? + .build(format!("{}/bindings.rs", std::env::var("OUT_DIR")?))?; + Ok(()) +} diff --git a/examples/math.rs b/examples/math.rs new file mode 100644 index 0000000..fbf9d21 --- /dev/null +++ b/examples/math.rs @@ -0,0 +1,26 @@ +//! Example demonstrating the use of the `import_python!` macro for the "math" module. +//! +//! Python equivalent: +//! +//! ```py +//! import math +//! +//! python_pi = math.pi +//! assert python_pi == 3.141592653589793 +//! print(f"Python Pi: {python_pi}") +//! ``` + +pyo3_bindgen::import_python!("math"); + +fn main() { + // Which Pi do you prefer? + // a) 🐍 Pi from Python "math" module + // b) 🦀 Pi from Rust standard library + // c) 🥧 Pi from your favorite bakery + pyo3::Python::with_gil(|py| { + let python_pi = math::pi(py).unwrap(); + let rust_pi = std::f64::consts::PI; + assert_eq!(python_pi, rust_pi); + println!("Python Pi: {}", python_pi); + }) +} diff --git a/examples/os_sys.rs b/examples/os_sys.rs new file mode 100644 index 0000000..1242c7b --- /dev/null +++ b/examples/os_sys.rs @@ -0,0 +1,34 @@ +//! Example demonstrating the use of the `pyo3_bindgen` crate via build script for +//! the "os", "posixpath", and "sys" Python modules. +//! +//! See `build.rs` for more details about the generation. +//! +//! Python equivalent: +//! +//! ```py +//! import os +//! import posixpath +//! import sys +//! +//! python_exe_path = sys.executable +//! current_dir = os.getcwd() +//! relpath_to_python_exe = posixpath.relpath(python_exe_path, current_dir) +//! +//! print(f"Relative path to Python executable: '{relpath_to_python_exe}'") +//! ``` + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +fn main() -> pyo3::PyResult<()> { + pyo3::Python::with_gil(|py| { + // Get the path to the Python executable via "sys" Python module + let python_exe_path = sys::executable(py)?; + // Get the current working directory via "os" Python module + let current_dir = os::getcwd(py)?; + // Get the relative path to the Python executable via "posixpath" Python module + let relpath_to_python_exe = posixpath::relpath(py, python_exe_path, current_dir)?; + + println!("Relative path to Python executable: '{relpath_to_python_exe}'"); + Ok(()) + }) +} diff --git a/examples/pygal.rs b/examples/pygal.rs new file mode 100644 index 0000000..10ef64a --- /dev/null +++ b/examples/pygal.rs @@ -0,0 +1,33 @@ +//! Example demonstrating the use of the `import_python!` macro for the "pygal" module. +//! +//! Python equivalent: +//! +//! ```py +//! import pygal +//! +//! bar_chart = pygal.Bar(style=pygal.style.DarkStyle) +//! bar_chart.add("Fibonacci", [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]) +//! bar_chart.add("Padovan", [1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12]) +//! svg = bar_chart.render(false) +//! print(svg) +//! ``` + +pyo3_bindgen::import_python!("pygal"); + +fn main() -> pyo3::PyResult<()> { + pyo3::Python::with_gil(|py| { + let bar_chart = pygal::Bar::new( + py, + (), + Some(pyo3::types::IntoPyDict::into_py_dict( + [("style", pygal::style::DarkStyle::new(py, None)?)], + py, + )), + )?; + bar_chart.add(py, "Fibonacci", [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55], None)?; + bar_chart.add(py, "Padovan", [1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12], None)?; + let svg = bar_chart.render(py, false, None)?; + println!("{svg}"); + Ok(()) + }) +} diff --git a/examples/random.rs b/examples/random.rs new file mode 100644 index 0000000..4903e2c --- /dev/null +++ b/examples/random.rs @@ -0,0 +1,22 @@ +//! Example demonstrating the use of the `import_python!` macro for the "random" module. +//! +//! Python equivalent: +//! +//! ```py +//! import random +//! +//! rand_f64 = random.random() +//! assert 0.0 <= rand_f64 <= 1.0 +//! print(f"Random f64: {rand_f64}") +//! ``` + +pyo3_bindgen::import_python!("random"); + +fn main() -> pyo3::PyResult<()> { + pyo3::Python::with_gil(|py| { + let rand_f64: f64 = random::random(py)?.extract()?; + assert!((0.0..=1.0).contains(&rand_f64)); + println!("Random f64: {}", rand_f64); + Ok(()) + }) +}