pyoxidizerlib/
python_distributions.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Defines known Python distributions.
6
7use {
8    crate::py_packaging::distribution::{DistributionFlavor, PythonDistributionRecord},
9    itertools::Itertools,
10};
11
12pub use crate::default_python_distributions::PYTHON_DISTRIBUTIONS;
13
14/// Default Python X.Y version to use.
15pub const DEFAULT_PYTHON_VERSION: &str = "3.10";
16
17/// A collection of available Python distributions.
18pub struct PythonDistributionCollection {
19    pub(crate) dists: Vec<PythonDistributionRecord>,
20}
21
22impl PythonDistributionCollection {
23    /// Find a Python distribution given requirements.
24    ///
25    /// `target_triple` is the Rust machine triple the distribution is built for.
26    /// `flavor` is the type of Python distribution.
27    /// `python_major_minor_version` is an optional `X.Y` version string being
28    /// requested. If `None`, `3.9` is assumed.
29    pub fn find_distribution(
30        &self,
31        target_triple: &str,
32        flavor: &DistributionFlavor,
33        python_major_minor_version: Option<&str>,
34    ) -> Option<PythonDistributionRecord> {
35        let python_major_minor_version =
36            python_major_minor_version.unwrap_or(DEFAULT_PYTHON_VERSION);
37
38        self.dists
39            .iter()
40            .filter(|dist| dist.python_major_minor_version == python_major_minor_version)
41            .filter(|dist| dist.target_triple == target_triple)
42            .filter(|dist| match flavor {
43                DistributionFlavor::Standalone => true,
44                DistributionFlavor::StandaloneStatic => !dist.supports_prebuilt_extension_modules,
45                DistributionFlavor::StandaloneDynamic => dist.supports_prebuilt_extension_modules,
46            })
47            .next()
48            .cloned()
49    }
50
51    /// Obtain records for all registered distributions.
52    #[allow(unused)]
53    pub fn iter(&self) -> impl Iterator<Item = &PythonDistributionRecord> {
54        self.dists.iter()
55    }
56
57    /// All target triples of distributions in this collection.
58    #[allow(unused)]
59    pub fn all_target_triples(&self) -> impl Iterator<Item = &str> {
60        self.dists
61            .iter()
62            .map(|dist| dist.target_triple.as_str())
63            .sorted()
64            .dedup()
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn test_all_target_triples() {
74        assert_eq!(
75            PYTHON_DISTRIBUTIONS
76                .all_target_triples()
77                .collect::<Vec<_>>(),
78            vec![
79                "aarch64-apple-darwin",
80                "aarch64-unknown-linux-gnu",
81                "i686-pc-windows-msvc",
82                "x86_64-apple-darwin",
83                "x86_64-pc-windows-msvc",
84                "x86_64-unknown-linux-gnu",
85                "x86_64-unknown-linux-musl",
86                "x86_64_v2-unknown-linux-gnu",
87                "x86_64_v2-unknown-linux-musl",
88                "x86_64_v3-unknown-linux-gnu",
89                "x86_64_v3-unknown-linux-musl",
90            ]
91        );
92    }
93}