Skip to main content

ty_python_core/
platform.rs

1use std::fmt::{Display, Formatter};
2use ty_combine::Combine;
3
4/// The target platform to assume when resolving types.
5#[derive(Debug, Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
6#[cfg_attr(
7    feature = "serde",
8    derive(serde::Serialize, serde::Deserialize, ruff_macros::RustDoc),
9    serde(rename_all = "kebab-case")
10)]
11pub enum PythonPlatform {
12    /// Do not make any assumptions about the target platform.
13    All,
14
15    /// Assume a specific target platform like `linux`, `darwin` or `win32`.
16    ///
17    /// We use a string (instead of individual enum variants), as the set of possible platforms
18    /// may change over time. See <https://docs.python.org/3/library/sys.html#sys.platform> for
19    /// some known platform identifiers.
20    #[cfg_attr(feature = "serde", serde(untagged))]
21    Identifier(String),
22}
23
24impl From<String> for PythonPlatform {
25    fn from(platform: String) -> Self {
26        match platform.as_str() {
27            "all" => PythonPlatform::All,
28            _ => PythonPlatform::Identifier(platform.clone()),
29        }
30    }
31}
32
33impl Display for PythonPlatform {
34    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35        match self {
36            PythonPlatform::All => f.write_str("all"),
37            PythonPlatform::Identifier(name) => f.write_str(name),
38        }
39    }
40}
41
42impl Default for PythonPlatform {
43    fn default() -> Self {
44        if cfg!(target_os = "windows") {
45            PythonPlatform::Identifier("win32".to_string())
46        } else if cfg!(target_os = "macos") {
47            PythonPlatform::Identifier("darwin".to_string())
48        } else if cfg!(target_os = "android") {
49            PythonPlatform::Identifier("android".to_string())
50        } else if cfg!(target_os = "ios") {
51            PythonPlatform::Identifier("ios".to_string())
52        } else {
53            PythonPlatform::Identifier("linux".to_string())
54        }
55    }
56}
57
58impl Combine for PythonPlatform {
59    fn combine_with(&mut self, _other: Self) {}
60}
61
62#[cfg(feature = "schemars")]
63mod schema {
64    use super::PythonPlatform;
65    use ruff_db::RustDoc;
66    use schemars::{JsonSchema, Schema, SchemaGenerator};
67    use serde_json::Value;
68
69    impl JsonSchema for PythonPlatform {
70        fn schema_name() -> std::borrow::Cow<'static, str> {
71            std::borrow::Cow::Borrowed("PythonPlatform")
72        }
73
74        fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
75            fn constant(value: &str, description: &str) -> Value {
76                let mut schema = schemars::json_schema!({ "const": value });
77                schema.ensure_object().insert(
78                    "description".to_string(),
79                    Value::String(description.to_string()),
80                );
81                schema.into()
82            }
83
84            // Hard code some well known values, but allow any other string as well.
85            let mut any_of = vec![schemars::json_schema!({ "type": "string" }).into()];
86            // Promote well-known values for better auto-completion.
87            // Using `const` over `enumValues` as recommended [here](https://github.com/SchemaStore/schemastore/blob/master/CONTRIBUTING.md#documenting-enums).
88            any_of.push(constant(
89                "all",
90                "Do not make any assumptions about the target platform.",
91            ));
92            any_of.push(constant("darwin", "Darwin"));
93            any_of.push(constant("linux", "Linux"));
94            any_of.push(constant("win32", "Windows"));
95
96            let mut schema = Schema::default();
97            let object = schema.ensure_object();
98            object.insert("anyOf".to_string(), Value::Array(any_of));
99            object.insert(
100                "description".to_string(),
101                Value::String(<PythonPlatform as RustDoc>::rust_doc().to_string()),
102            );
103
104            schema
105        }
106    }
107}