libgir/analysis/
conversion_type.rs

1use std::sync::Arc;
2
3use crate::{env, library::*};
4
5#[derive(Default, Clone, Debug, Eq, PartialEq)]
6pub enum ConversionType {
7    /// Coded without conversion.
8    Direct,
9    /// Coded with from_glib.
10    Scalar,
11    /// Type implementing TryFromGlib<Error=GlibNoneError>.
12    Option,
13    /// Type implementing TryFromGlib<Err> where Err is neither GlibNoneError
14    /// nor GlibNoneOrInvalidError. Embeds the Error type name.
15    /// Defaults to the object's type for the `Ok` variant if `ok_type` is
16    /// `None`.
17    Result {
18        ok_type: Arc<str>,
19        err_type: Arc<str>,
20    },
21    /// Coded with from_glib_xxx.
22    Pointer,
23    // Same as Pointer, except that use from_glib_borrow instead from_glib_none.
24    Borrow,
25    #[default]
26    Unknown,
27}
28
29impl ConversionType {
30    pub fn of(env: &env::Env, type_id: TypeId) -> Self {
31        use crate::library::{Basic::*, Type::*};
32
33        let library = &env.library;
34
35        if let Some(conversion_type) = env
36            .config
37            .objects
38            .get(&type_id.full_name(library))
39            .and_then(|gobject| gobject.conversion_type.clone())
40        {
41            return conversion_type;
42        }
43
44        match library.type_(type_id) {
45            Basic(fund) => match fund {
46                Boolean => Self::Scalar,
47                Int8 => Self::Direct,
48                UInt8 => Self::Direct,
49                Int16 => Self::Direct,
50                UInt16 => Self::Direct,
51                Int32 => Self::Direct,
52                UInt32 => Self::Direct,
53                Int64 => Self::Direct,
54                UInt64 => Self::Direct,
55                Char => Self::Scalar,
56                UChar => Self::Scalar,
57                Short => Self::Direct,
58                UShort => Self::Direct,
59                Int => Self::Direct,
60                UInt => Self::Direct,
61                Long => Self::Direct,
62                ULong => Self::Direct,
63                Size => Self::Direct,
64                SSize => Self::Direct,
65                Float => Self::Direct,
66                Double => Self::Direct,
67                UniChar => Self::Scalar,
68                Pointer => Self::Pointer,
69                VarArgs => Self::Unknown,
70                Utf8 => Self::Pointer,
71                Filename => Self::Pointer,
72                OsString => Self::Pointer,
73                Type => Self::Scalar,
74                TimeT => Self::Direct,
75                OffT => Self::Direct,
76                DevT => Self::Direct,
77                GidT => Self::Direct,
78                PidT => Self::Direct,
79                SockLenT => Self::Direct,
80                UidT => Self::Direct,
81                None => Self::Unknown,
82                IntPtr => Self::Direct,
83                UIntPtr => Self::Direct,
84                Bool => Self::Direct,
85                Unsupported => Self::Unknown,
86            },
87            Alias(alias) if alias.c_identifier == "GQuark" => Self::Scalar,
88            Alias(alias) => Self::of(env, alias.typ),
89            Bitfield(_) => Self::Scalar,
90            Record(_) => Self::Pointer,
91            Union(_) => Self::Pointer,
92            Enumeration(_) => Self::Scalar,
93            Interface(_) => Self::Pointer,
94            Class(_) => Self::Pointer,
95            CArray(_) => Self::Pointer,
96            FixedArray(..) => Self::Pointer,
97            List(_) => Self::Pointer,
98            SList(_) => Self::Pointer,
99            PtrArray(_) => Self::Pointer,
100            Function(super::library::Function { name, .. }) if name == "AsyncReadyCallback" => {
101                Self::Direct
102            }
103            Function(_) => Self::Direct,
104            Custom(super::library::Custom {
105                conversion_type, ..
106            }) => conversion_type.clone(),
107            _ => Self::Unknown,
108        }
109    }
110
111    pub fn can_use_to_generate(&self) -> bool {
112        matches!(self, Self::Option | Self::Result { .. })
113    }
114}