abi_stable/reflection/
export_module.rs
1use std::fmt::{self, Display};
4
5use core_extensions::SelfOps;
6
7use crate::{reflection::ModReflMode, type_layout::*};
8
9#[derive(Debug, Serialize, Deserialize)]
10pub struct MRItem {
11 item_name: String,
12 type_: String,
13 field_accessor: MRFieldAccessor,
14 #[serde(flatten)]
15 variant: MRItemVariant,
16}
17
18#[derive(Debug, Serialize, Deserialize)]
19pub struct MRNameType {
20 name: String,
21 type_: String,
22}
23
24#[derive(Debug, Serialize, Deserialize)]
25#[serde(tag = "variant")]
26pub enum MRItemVariant {
27 Function(MRFunction),
28 Module(MRModule),
29 Static,
30}
31
32#[derive(Debug, Serialize, Deserialize)]
33pub struct MRFunction {
34 params: Vec<MRNameType>,
35 returns: MRNameType,
36}
37
38#[derive(Debug, Serialize, Deserialize)]
39pub struct MRModule {
40 mod_refl_mode: MRModReflMode,
41 items: Vec<MRItem>,
42}
43
44#[derive(Debug, Serialize, Deserialize)]
45pub enum MRModReflMode {
46 Module,
47 Opaque,
48 DelegateDeref,
49}
50
51#[repr(u8)]
52#[derive(Debug, Serialize, Deserialize)]
53pub enum MRFieldAccessor {
54 Direct,
56 Method { name: Option<String> },
58 MethodOption,
60 Opaque,
62}
63
64impl MRItem {
65 pub fn from_type_layout(layout: &'static TypeLayout) -> Self {
66 let type_ = layout.full_type().to_string();
67
68 let variant = Self::get_item_variant(layout);
69
70 Self {
71 item_name: "root".into(),
72 type_,
73 field_accessor: MRFieldAccessor::Direct,
74 variant,
75 }
76 }
77
78 fn get_item_variant(layout: &'static TypeLayout) -> MRItemVariant {
79 match layout.mod_refl_mode() {
80 ModReflMode::Module => {
81 let fields = match layout.data() {
82 TLData::Struct { fields } => fields,
83 TLData::PrefixType(prefix) => prefix.fields,
84 TLData::Primitive { .. }
85 | TLData::Opaque { .. }
86 | TLData::Union { .. }
87 | TLData::Enum { .. } => return MRItemVariant::Static,
88 };
89
90 let items = fields
91 .iter()
92 .filter(|f| f.field_accessor() != FieldAccessor::Opaque)
93 .map(|field| {
94 let (type_, variant) = if field.is_function() {
95 let func = MRFunction::from(&field.function_range().index(0));
96 (func.to_string(), MRItemVariant::Function(func))
97 } else {
98 let layout = field.layout();
99 (
100 layout.full_type().to_string(),
101 Self::get_item_variant(layout),
102 )
103 };
104 MRItem {
105 item_name: field.name().to_string(),
106 type_,
107 field_accessor: field.field_accessor().into(),
108 variant,
109 }
110 })
111 .collect::<Vec<_>>();
112 MRItemVariant::Module(MRModule {
113 mod_refl_mode: layout.mod_refl_mode().into(),
114 items,
115 })
116 }
117 ModReflMode::Opaque => MRItemVariant::Static,
118 ModReflMode::DelegateDeref { layout_index } => {
119 let delegate_to = layout.shared_vars().type_layouts()[layout_index as usize];
120 let inner_layout = delegate_to();
121 Self::get_item_variant(inner_layout)
122 }
123 }
124 }
125}
126
127impl<'a> From<&'a TLFunction> for MRFunction {
130 fn from(this: &'a TLFunction) -> Self {
131 Self {
132 params: this.get_params().map(MRNameType::from).collect::<Vec<_>>(),
133 returns: this.get_return().into_::<MRNameType>(),
134 }
135 }
136}
137
138impl Display for MRFunction {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(f, "fn(")?;
141 let param_count = self.params.len();
142 for (param_i, param) in self.params.iter().enumerate() {
143 Display::fmt(param, f)?;
144 if param_i + 1 != param_count {
145 Display::fmt(&", ", f)?;
146 }
147 }
148 write!(f, ")")?;
149
150 let returns = &self.returns;
151 Display::fmt(&"->", f)?;
152 Display::fmt(returns, f)?;
153
154 Ok(())
155 }
156}
157
158impl From<TLField> for MRNameType {
161 fn from(field: TLField) -> Self {
162 let name = field.name().to_string();
163 let type_ = if field.is_function() {
164 field.function_range().index(0).to_string()
165 } else {
166 field.layout().full_type().to_string()
167 };
168
169 Self { name, type_ }
170 }
171}
172
173impl Display for MRNameType {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 write!(f, "{}:{}", self.name, self.type_)
176 }
177}
178
179impl From<ModReflMode> for MRModReflMode {
182 fn from(this: ModReflMode) -> Self {
183 match this {
184 ModReflMode::Module { .. } => MRModReflMode::Module,
185 ModReflMode::Opaque { .. } => MRModReflMode::Opaque,
186 ModReflMode::DelegateDeref { .. } => MRModReflMode::DelegateDeref,
187 }
188 }
189}
190
191impl From<FieldAccessor> for MRFieldAccessor {
194 fn from(this: FieldAccessor) -> MRFieldAccessor {
195 match this {
196 FieldAccessor::Direct => MRFieldAccessor::Direct,
197 FieldAccessor::Method => MRFieldAccessor::Method { name: None },
198 FieldAccessor::MethodNamed { name } => MRFieldAccessor::Method {
199 name: Some(name.to_string()),
200 },
201 FieldAccessor::MethodOption => MRFieldAccessor::MethodOption,
202 FieldAccessor::Opaque => MRFieldAccessor::Opaque,
203 }
204 }
205}