1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright (c) ZeroC, Inc.

use super::elements::*;
use super::traits::*;
use crate::slice_file::SliceFile;
use crate::utils::ptr_util::WeakPtr;

macro_rules! generate_definition_wrapper {
    ($($variant:ident),*) => {
        #[derive(Debug)]
        pub enum Definition {
            $($variant(WeakPtr<$variant>),)*
        }

        impl Definition {
            #[allow(clippy::should_implement_trait)]
            pub fn borrow(&self) -> &dyn Entity {
                match self {
                    $(Self::$variant(x) => x.borrow(),)*
                }
            }
        }
    };
}

generate_definition_wrapper!(Struct, Class, Exception, Interface, Enum, CustomType, TypeAlias);

macro_rules! generate_entities_wrapper {
    ($($variant:ident),*) => {
        #[derive(Debug)]
        pub enum Entities<'a> {
            $($variant(&'a $variant),)*
        }

        $(
        impl AsEntities for $variant {
            fn concrete_entity(&self) -> Entities {
                Entities::$variant(self)
            }
        }
        )*
    };
}

pub trait AsEntities {
    fn concrete_entity(&self) -> Entities;
}

generate_entities_wrapper!(
    Struct, Class, Exception, Field, Interface, Operation, Parameter, Enum, Enumerator, CustomType, TypeAlias
);

macro_rules! generate_attributables_wrapper {
    ($($variant:ident),*) => {
        #[derive(Debug)]
        pub enum Attributables<'a> {
            $($variant(&'a $variant),)*
        }

        $(
        impl AsAttributables for $variant {
            fn concrete_attributable(&self) -> Attributables {
                Attributables::$variant(self)
            }
        }
        )*
    };
}

pub trait AsAttributables {
    fn concrete_attributable(&self) -> Attributables;
}

generate_attributables_wrapper!(
    Module, Struct, Class, Exception, Field, Interface, Operation, Parameter, Enum, Enumerator, CustomType, TypeAlias,
    TypeRef, SliceFile
);

macro_rules! generate_types_wrapper {
    ($($variant:ident),*) => {
        #[derive(Debug)]
        pub enum Types<'a> {
            $($variant(&'a $variant),)*
        }

        $(
        impl AsTypes for $variant {
            fn concrete_type(&self) -> Types {
                Types::$variant(self)
            }
        }
        )*

        #[derive(Debug)]
        pub enum TypeRefs {
            $($variant(TypeRef<$variant>),)*
        }

        impl<T: Type + ?Sized> TypeRef<T> {
            pub fn concrete_typeref(&self) -> TypeRefs {
                match self.definition().concrete_type() {
                    $(Types::$variant(_) => TypeRefs::$variant(
                        self.downcast::<$variant>().ok().unwrap(),
                    ),)*
                }
            }
        }
    };
}

pub trait AsTypes {
    fn concrete_type(&self) -> Types;
}

generate_types_wrapper!(Struct, Class, Enum, CustomType, ResultType, Sequence, Dictionary, Primitive);