windows-bindgen 0.66.0

Code generator for Windows metadata
Documentation
use super::*;

impl std::fmt::Debug for TypeDef {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "TypeDef({})", self.type_name())
    }
}

impl TypeDef {
    pub fn flags(&self) -> TypeAttributes {
        TypeAttributes(self.usize(0) as u32)
    }

    pub fn type_name(&self) -> TypeName {
        TypeName(self.namespace(), self.name())
    }

    pub fn name(&self) -> &'static str {
        trim_tick(self.str(1))
    }

    pub fn namespace(&self) -> &'static str {
        self.str(2)
    }

    pub fn extends(&self) -> Option<TypeName> {
        let extends = self.usize(3);

        if extends == 0 {
            return None;
        }

        Some(TypeDefOrRef::decode(self.file(), extends).type_name())
    }

    pub fn methods(&self) -> RowIterator<MethodDef> {
        self.list(5)
    }

    pub fn fields(&self) -> RowIterator<Field> {
        self.list(4)
    }

    pub fn generics(&self) -> Vec<Type> {
        self.file()
            .equal_range(2, TypeOrMethodDef::TypeDef(*self).encode())
            .map(|generic: GenericParam| Type::Generic(generic))
            .collect()
    }

    pub fn interface_impls(&self) -> RowIterator<InterfaceImpl> {
        self.file().equal_range(0, self.index() + 1)
    }

    pub fn class_layout(&self) -> Option<ClassLayout> {
        self.file().equal_range(2, self.index() + 1).next()
    }

    pub fn nested(&self) -> Option<NestedClass> {
        self.file().equal_range(0, self.index() + 1).next()
    }

    pub fn underlying_type(&self) -> Type {
        let field = self.fields().next().unwrap();
        if let Some(constant) = field.constant() {
            constant.ty()
        } else {
            field.ty(None)
        }
    }

    pub fn invalid_values(&self) -> Vec<i64> {
        let mut values = Vec::new();
        for attribute in self.attributes() {
            if attribute.name() == "InvalidHandleValueAttribute" {
                if let Some((_, Value::I64(value))) = attribute.args().first() {
                    values.push(*value);
                }
            }
        }
        values
    }

    pub fn free_function(&self) -> Option<CppFn> {
        if let Some(attribute) = self.find_attribute("RAIIFreeAttribute") {
            if let Some((_, Value::Str(name))) = attribute.args().first() {
                if let Some(Type::CppFn(ty)) =
                    self.reader().with_full_name(self.namespace(), name).next()
                {
                    return Some(ty);
                }
            }
        }

        None
    }

    pub fn is_agile(&self) -> bool {
        for attribute in self.attributes() {
            match attribute.name() {
                "AgileAttribute" => return true,
                "MarshalingBehaviorAttribute" => {
                    if let Some((_, Value::I32(2))) = attribute.args().first() {
                        return true;
                    }
                }
                _ => {}
            }
        }

        self.is_async()
    }

    pub fn is_async(&self) -> bool {
        matches!(
            TypeName(self.namespace(), self.name()),
            TypeName::IAsyncAction
                | TypeName::IAsyncActionWithProgress
                | TypeName::IAsyncOperation
                | TypeName::IAsyncOperationWithProgress
        )
    }
}