codify/python/
type.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{
4    prelude::{fmt, format, Cow, Named},
5    rust,
6};
7
8/// See: https://docs.python.org/3/library/stdtypes.html
9#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum Type {
12    NoneType,
13
14    /// See: https://docs.python.org/3/library/stdtypes.html#boolean-type-bool
15    Bool,
16
17    /// See: https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex
18    Float,
19
20    /// See: https://docs.python.org/3/library/ctypes.html#fundamental-data-types
21    #[cfg(feature = "language-c")]
22    Ffi(crate::c::Type),
23}
24
25impl core::str::FromStr for Type {
26    type Err = ();
27
28    fn from_str(input: &str) -> Result<Self, Self::Err> {
29        use Type::*;
30        Ok(match input {
31            "NoneType" => NoneType,
32            "bool" => Bool,
33            "float" => Float,
34            _ => return Err(()),
35        })
36    }
37}
38
39impl fmt::Display for Type {
40    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        use Type::*;
42        match self {
43            NoneType => write!(f, "NoneType"),
44            Bool => write!(f, "bool"),
45            Float => write!(f, "float"),
46            #[cfg(feature = "language-c")]
47            Ffi(t) => match t {
48                // See: https://docs.python.org/3/library/ctypes.html#fundamental-data-types
49                crate::c::Type::Void => write!(f, "None"),
50                crate::c::Type::Bool => write!(f, "c_bool"),
51                crate::c::Type::Float => write!(f, "c_float"),
52                crate::c::Type::Double => write!(f, "c_double"),
53                crate::c::Type::Char => write!(f, "c_char"),
54                crate::c::Type::SChar => write!(f, "c_byte"),
55                crate::c::Type::Short => write!(f, "c_short"),
56                crate::c::Type::Int => write!(f, "c_int"),
57                crate::c::Type::Long => write!(f, "c_long"),
58                crate::c::Type::LongLong => write!(f, "c_longlong"),
59                crate::c::Type::SSize_t => write!(f, "c_ssize_t"),
60                crate::c::Type::UChar => write!(f, "c_ubyte"),
61                crate::c::Type::UShort => write!(f, "c_ushort"),
62                crate::c::Type::UInt => write!(f, "c_uint"),
63                crate::c::Type::ULong => write!(f, "c_ulong"),
64                crate::c::Type::ULongLong => write!(f, "c_ulonglong"),
65                crate::c::Type::Size_t => write!(f, "c_size_t"),
66                crate::c::Type::Array(t, None) => write!(f, "POINTER({})", Ffi((**t).clone())),
67                crate::c::Type::Array(t, Some(n)) => write!(f, "{} * {}", Ffi((**t).clone()), n),
68                crate::c::Type::Ptr(t) if **t == crate::c::Type::Char => write!(f, "c_char_p"),
69                crate::c::Type::PtrMut(t) if **t == crate::c::Type::Char => write!(f, "c_char_p"),
70                crate::c::Type::Ptr(t) if **t == crate::c::Type::Void => write!(f, "c_void_p"),
71                crate::c::Type::PtrMut(t) if **t == crate::c::Type::Void => write!(f, "c_void_p"),
72                crate::c::Type::Ptr(t) | crate::c::Type::PtrMut(t) => {
73                    write!(f, "POINTER({})", Ffi((**t).clone()))
74                }
75                #[cfg(feature = "libc")]
76                crate::c::Type::Time_t => write!(f, "c_time_t"),
77            },
78        }
79    }
80}
81
82impl Named for Type {
83    fn name(&self) -> Cow<str> {
84        Cow::Owned(format!("{}", self))
85    }
86}
87
88impl TryFrom<rust::Type> for Type {
89    type Error = ();
90
91    fn try_from(input: rust::Type) -> Result<Self, Self::Error> {
92        use Type::*;
93        Ok(match input {
94            rust::Type::Any => return Err(()),
95            rust::Type::Unit => NoneType,
96            rust::Type::Bool => Bool,
97            rust::Type::F32 | rust::Type::F64 => Float,
98            #[cfg(feature = "language-c")]
99            rust::Type::Ffi(t) => Type::Ffi(t),
100            _ => return Err(()),
101        })
102    }
103}
104
105impl crate::ToRust for Type {
106    fn to_rust(&self) -> Option<rust::Type> {
107        use Type::*;
108        Some(match self {
109            NoneType => rust::Type::Unit,
110            Bool => rust::Type::Bool,
111            Float => rust::Type::F64,
112            #[cfg(feature = "language-c")]
113            Ffi(t) => rust::Type::Ffi(t.clone()),
114        })
115    }
116}
117
118impl crate::Type for Type {}