1use crate::bytecode::{FunctionKey, MetadataKey, MetadataObjs, VMObjects};
6use crate::gc::GcContainer;
7use crate::instruction::{OpIndex, ValueType};
8use crate::objects::{IfaceBinding, StructObj};
9use crate::value::ArrCaller;
10use crate::value::GosValue;
11#[cfg(feature = "serde_borsh")]
12use borsh::{
13 maybestd::io::Result as BorshResult, maybestd::io::Write as BorshWrite, BorshDeserialize,
14 BorshSerialize,
15};
16use go_parser::Map;
17use std::cell::RefCell;
18use std::rc::Rc;
19
20#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
21#[derive(PartialEq, Eq, Clone, Debug)]
22pub enum ChannelType {
23 Send,
24 Recv,
25 SendRecv,
26}
27
28#[derive(Debug)]
29pub struct PrimitiveMeta {
30 pub mbool: Meta,
31 pub mint: Meta,
32 pub mint8: Meta,
33 pub mint16: Meta,
34 pub mint32: Meta,
35 pub mint64: Meta,
36 pub muint: Meta,
37 pub muint_ptr: Meta,
38 pub muint8: Meta,
39 pub muint16: Meta,
40 pub muint32: Meta,
41 pub muint64: Meta,
42 pub mfloat32: Meta,
43 pub mfloat64: Meta,
44 pub mcomplex64: Meta,
45 pub mcomplex128: Meta,
46 pub mstr: Meta,
47 pub unsafe_ptr: Meta,
48 pub default_sig: Meta,
49 pub empty_iface: Meta,
50 pub none: Meta,
51}
52
53impl PrimitiveMeta {
54 pub fn new(objs: &mut MetadataObjs) -> PrimitiveMeta {
55 PrimitiveMeta {
56 mbool: Meta::with_type(MetadataType::Bool, objs),
57 mint: Meta::with_type(MetadataType::Int, objs),
58 mint8: Meta::with_type(MetadataType::Int8, objs),
59 mint16: Meta::with_type(MetadataType::Int16, objs),
60 mint32: Meta::with_type(MetadataType::Int32, objs),
61 mint64: Meta::with_type(MetadataType::Int64, objs),
62 muint: Meta::with_type(MetadataType::Uint, objs),
63 muint_ptr: Meta::with_type(MetadataType::UintPtr, objs),
64 muint8: Meta::with_type(MetadataType::Uint8, objs),
65 muint16: Meta::with_type(MetadataType::Uint16, objs),
66 muint32: Meta::with_type(MetadataType::Uint32, objs),
67 muint64: Meta::with_type(MetadataType::Uint64, objs),
68 mfloat32: Meta::with_type(MetadataType::Float32, objs),
69 mfloat64: Meta::with_type(MetadataType::Float64, objs),
70 mcomplex64: Meta::with_type(MetadataType::Complex64, objs),
71 mcomplex128: Meta::with_type(MetadataType::Complex128, objs),
72 mstr: Meta::with_type(MetadataType::Str, objs),
73 unsafe_ptr: Meta::with_type(MetadataType::UnsafePtr, objs),
74 default_sig: Meta::with_type(MetadataType::Signature(SigMetadata::default()), objs),
75 empty_iface: Meta::with_type(MetadataType::Interface(Fields::new(vec![])), objs),
76 none: Meta::with_type(MetadataType::None, objs),
77 }
78 }
79}
80
81#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
83pub struct Meta {
84 pub key: MetadataKey,
85 pub ptr_depth: u8,
86 pub is_type: bool,
87}
88
89impl Meta {
90 #[inline]
91 pub fn new(key: MetadataKey, pdepth: u8, is_type: bool) -> Meta {
92 Meta {
93 key: key,
94 ptr_depth: pdepth,
95 is_type: is_type,
96 }
97 }
98
99 #[inline]
100 pub fn with_type(v: MetadataType, metas: &mut MetadataObjs) -> Meta {
101 Meta::new(metas.insert(v), 0, false)
102 }
103
104 #[inline]
105 pub fn new_array(elem_meta: Meta, size: usize, metas: &mut MetadataObjs) -> Meta {
106 let t = MetadataType::Array(elem_meta, size);
107 Meta {
108 key: metas.insert(t),
109 ptr_depth: 0,
110 is_type: false,
111 }
112 }
113
114 #[inline]
115 pub fn new_slice(val_meta: Meta, metas: &mut MetadataObjs) -> Meta {
116 Meta::with_type(MetadataType::Slice(val_meta), metas)
117 }
118
119 #[inline]
120 pub fn new_map(kmeta: Meta, vmeta: Meta, metas: &mut MetadataObjs) -> Meta {
121 Meta::with_type(MetadataType::Map(kmeta, vmeta), metas)
122 }
123
124 #[inline]
125 pub fn new_interface(fields: Fields, metas: &mut MetadataObjs) -> Meta {
126 Meta::with_type(MetadataType::Interface(fields), metas)
127 }
128
129 #[inline]
130 pub fn new_channel(typ: ChannelType, val_meta: Meta, metas: &mut MetadataObjs) -> Meta {
131 Meta::with_type(MetadataType::Channel(typ, val_meta), metas)
132 }
133
134 #[inline]
135 pub(crate) fn new_struct(f: Fields, objs: &mut VMObjects) -> Meta {
136 let key = objs.metas.insert(MetadataType::Struct(f));
137 Meta::new(key, 0, false)
138 }
139
140 pub fn new_sig(
141 recv: Option<Meta>,
142 params: Vec<Meta>,
143 results: Vec<Meta>,
144 variadic: Option<(Meta, Meta)>,
145 metas: &mut MetadataObjs,
146 ) -> Meta {
147 let params_type = params.iter().map(|x| x.value_type(metas)).collect();
148 let t = MetadataType::Signature(SigMetadata {
149 recv,
150 params,
151 results,
152 variadic,
153 params_type,
154 });
155 Meta::with_type(t, metas)
156 }
157
158 pub fn new_named(underlying: Meta, metas: &mut MetadataObjs) -> Meta {
159 Meta::with_type(MetadataType::Named(Methods::new(), underlying), metas)
161 }
162
163 #[inline]
164 pub fn mtype_unwraped<'a>(&self, metas: &'a MetadataObjs) -> &'a MetadataType {
165 metas[self.key].unwrap_named(metas)
166 }
167
168 #[inline]
169 pub fn ptr_to(&self) -> Meta {
170 let mut m = *self;
171 m.ptr_depth += 1;
172 m
173 }
174
175 #[inline]
176 pub fn unptr_to(&self) -> Meta {
177 assert!(self.ptr_depth > 0);
178 let mut m = *self;
179 m.ptr_depth -= 1;
180 m
181 }
182
183 #[inline]
184 pub fn into_type_category(mut self) -> Meta {
185 self.is_type = true;
186 self
187 }
188
189 #[inline]
190 pub fn into_value_category(mut self) -> Meta {
191 self.is_type = false;
192 self
193 }
194
195 #[inline]
196 pub fn value_type(&self, metas: &MetadataObjs) -> ValueType {
197 match self.is_type {
198 false => match self.ptr_depth {
199 0 => match &metas[self.key] {
200 MetadataType::Bool => ValueType::Bool,
201 MetadataType::Int => ValueType::Int,
202 MetadataType::Int8 => ValueType::Int8,
203 MetadataType::Int16 => ValueType::Int16,
204 MetadataType::Int32 => ValueType::Int32,
205 MetadataType::Int64 => ValueType::Int64,
206 MetadataType::Uint => ValueType::Uint,
207 MetadataType::UintPtr => ValueType::UintPtr,
208 MetadataType::Uint8 => ValueType::Uint8,
209 MetadataType::Uint16 => ValueType::Uint16,
210 MetadataType::Uint32 => ValueType::Uint32,
211 MetadataType::Uint64 => ValueType::Uint64,
212 MetadataType::Float32 => ValueType::Float32,
213 MetadataType::Float64 => ValueType::Float64,
214 MetadataType::Complex64 => ValueType::Complex64,
215 MetadataType::Complex128 => ValueType::Complex128,
216 MetadataType::UnsafePtr => ValueType::UnsafePtr,
217 MetadataType::Str => ValueType::String,
218 MetadataType::Struct(_) => ValueType::Struct,
219 MetadataType::Signature(_) => ValueType::Closure,
220 MetadataType::Array(_, _) => ValueType::Array,
221 MetadataType::Slice(_) => ValueType::Slice,
222 MetadataType::Map(_, _) => ValueType::Map,
223 MetadataType::Interface(_) => ValueType::Interface,
224 MetadataType::Channel(_, _) => ValueType::Channel,
225 MetadataType::Named(_, m) => m.value_type(metas),
226 MetadataType::None => ValueType::Void,
227 },
228 _ => ValueType::Pointer,
229 },
230 true => ValueType::Metadata,
231 }
232 }
233
234 #[inline]
235 pub(crate) fn zero(&self, mobjs: &MetadataObjs, gcc: &GcContainer) -> GosValue {
236 match self.ptr_depth {
237 0 => match &mobjs[self.key] {
238 MetadataType::Bool => false.into(),
239 MetadataType::Int => 0isize.into(),
240 MetadataType::Int8 => 0i8.into(),
241 MetadataType::Int16 => 0i16.into(),
242 MetadataType::Int32 => 0i32.into(),
243 MetadataType::Int64 => 0i64.into(),
244 MetadataType::Uint => 0isize.into(),
245 MetadataType::UintPtr => GosValue::new_uint_ptr(0),
246 MetadataType::Uint8 => 0u8.into(),
247 MetadataType::Uint16 => 0u16.into(),
248 MetadataType::Uint32 => 0u32.into(),
249 MetadataType::Uint64 => 0u64.into(),
250 MetadataType::Float32 => GosValue::new_float32(0.0.into()),
251 MetadataType::Float64 => GosValue::new_float64(0.0.into()),
252 MetadataType::Complex64 => GosValue::new_complex64(0.0.into(), 0.0.into()),
253 MetadataType::Complex128 => GosValue::new_complex128(0.0.into(), 0.0.into()),
254 MetadataType::UnsafePtr => GosValue::new_nil(ValueType::UnsafePtr),
255 MetadataType::Str => GosValue::with_str(""),
256 MetadataType::Array(m, size) => {
257 let val = m.zero(mobjs, gcc);
258 let t = m.value_type(mobjs);
259 let caller = ArrCaller::get_slow(t);
260 GosValue::array_with_size(*size, *size, &val, &caller, gcc)
261 }
262 MetadataType::Slice(m) => GosValue::new_nil_slice(m.value_type(mobjs)),
263 MetadataType::Struct(f) => {
264 let field_zeros: Vec<GosValue> =
265 f.fields.iter().map(|x| x.meta.zero(mobjs, gcc)).collect();
266 let struct_val = StructObj::new(field_zeros);
267 GosValue::new_struct(struct_val, gcc)
268 }
269 MetadataType::Signature(_) => GosValue::new_nil(ValueType::Closure),
270 MetadataType::Map(_, _) => GosValue::new_nil(ValueType::Map),
271 MetadataType::Interface(_) => GosValue::new_nil(ValueType::Interface),
272 MetadataType::Channel(_, _) => GosValue::new_nil(ValueType::Channel),
273 MetadataType::Named(_, gm) => gm.zero(mobjs, gcc),
274 MetadataType::None => unreachable!(),
275 },
276 _ => GosValue::new_nil(ValueType::Pointer),
277 }
278 }
279
280 #[inline]
281 pub fn field_indices(&self, name: &str, metas: &MetadataObjs) -> Vec<usize> {
282 let key = self.recv_meta_key();
283 match &metas[Meta::new(key, 0, false).underlying(metas).key] {
284 MetadataType::Struct(m) => m.indices_by_name(name),
285 _ => unreachable!(),
286 }
287 }
288
289 #[inline]
290 pub fn underlying(&self, metas: &MetadataObjs) -> Meta {
291 match &metas[self.key] {
292 MetadataType::Named(_, u) => *u,
293 _ => *self,
294 }
295 }
296
297 #[inline]
298 pub fn recv_meta_key(&self) -> MetadataKey {
299 assert!(self.ptr_depth <= 1);
300 self.key
301 }
302
303 pub fn add_method(&self, name: String, pointer_recv: bool, metas: &mut MetadataObjs) {
304 let k = self.recv_meta_key();
305 match &mut metas[k] {
306 MetadataType::Named(m, _) => {
307 m.members.push(Rc::new(RefCell::new(MethodDesc {
308 pointer_recv: pointer_recv,
309 func: None,
310 })));
311 m.mapping.insert(name, m.members.len() as OpIndex - 1);
312 }
313 _ => unreachable!(),
314 }
315 }
316
317 pub fn set_method_code(&self, name: &String, func: FunctionKey, metas: &mut MetadataObjs) {
318 let k = self.recv_meta_key();
319 match &mut metas[k] {
320 MetadataType::Named(m, _) => {
321 let index = m.mapping[name] as usize;
322 m.members[index].borrow_mut().func = Some(func);
323 }
324 _ => unreachable!(),
325 }
326 }
327
328 fn get_iface_binding(&self, name: &String, metas: &MetadataObjs) -> Option<IfaceBinding> {
330 match &metas[self.key] {
331 MetadataType::Named(m, underlying) => match m.mapping.get(name) {
332 Some(&i) => Some(IfaceBinding::Struct(m.members[i as usize].clone(), None)),
333 None => underlying.get_iface_binding(name, metas),
334 },
335 MetadataType::Interface(fields) => fields
336 .try_index_by_name(name)
337 .map(|x| IfaceBinding::Iface(x, None)),
338 MetadataType::Struct(fields) => {
339 for (i, f) in fields.fields.iter().enumerate() {
340 if let Some(mut re) = f.meta.get_iface_binding(name, metas) {
341 let indices = match &mut re {
342 IfaceBinding::Struct(_, indices) | IfaceBinding::Iface(_, indices) => {
343 indices
344 }
345 };
346 if let Some(x) = indices {
347 x.push(i as OpIndex)
348 } else {
349 *indices = Some(vec![i as OpIndex]);
350 }
351 return Some(re);
352 }
353 }
354 None
355 }
356 _ => None,
357 }
358 }
359
360 #[inline]
361 pub fn get_method(&self, index: OpIndex, metas: &MetadataObjs) -> Rc<RefCell<MethodDesc>> {
362 let k = self.recv_meta_key();
363 let m = match &metas[k] {
364 MetadataType::Named(methods, _) => methods,
365 _ => unreachable!(),
366 };
367 m.members[index as usize].clone()
368 }
369
370 pub fn identical(&self, other: &Self, metas: &MetadataObjs) -> bool {
371 (self.key == other.key) || metas[self.key].identical(&metas[other.key], metas)
372 }
373
374 pub fn bind_with_iface(
375 &self,
376 value_meta: Self,
377 metas: &MetadataObjs,
378 ) -> (Meta, Vec<IfaceBinding>) {
379 let fields: Vec<&String> = match &metas[self.underlying(metas).key] {
380 MetadataType::Interface(m) => m.infos().iter().map(|x| &x.name).collect(),
381 _ => unreachable!(),
382 };
383 (
384 value_meta,
385 fields
386 .iter()
387 .map(|x| value_meta.get_iface_binding(x, metas).unwrap())
388 .collect(),
389 )
390 }
391}
392
393#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
394#[derive(Debug, Clone)]
395pub struct FieldInfo {
396 pub meta: Meta,
397 pub name: String,
398 pub tag: Option<String>,
399 pub embedded_indices: Option<Vec<usize>>,
401}
402
403impl FieldInfo {
404 pub fn exported(&self) -> bool {
405 self.name.chars().next().unwrap().is_uppercase()
406 }
407
408 pub fn lookup_tag(&self, key: &str) -> Option<String> {
409 if self.tag.is_none() {
410 return None;
411 }
412
413 let mut tag: &str = self.tag.as_ref().unwrap();
414 while !tag.is_empty() {
415 let i = tag.find(|c: char| c != ' ').unwrap_or(tag.len());
417 tag = &tag[i..];
418 if tag.is_empty() {
419 break;
420 }
421
422 let i = tag
424 .find(|c: char| c <= ' ' || c == ':' || c == '"' || c as u32 == 0x7f)
425 .unwrap_or(tag.len());
426
427 if i == 0 || i + 1 >= tag.len() || &tag[i..i + 1] != ":" || &tag[i + 1..i + 2] != "\"" {
428 break;
429 }
430
431 let name = &tag[..i];
432 tag = &tag[i + 1..];
433
434 let mut i = 1;
436 while i < tag.len() && &tag[i..i + 1] != "\"" {
437 if &tag[i..i + 1] == "\\" {
438 i += 1;
439 }
440 i += 1;
441 }
442
443 if i >= tag.len() {
444 break;
445 }
446
447 let qvalue = &tag[..i + 1];
448 tag = &tag[i + 1..];
449
450 if key == name {
451 let value = str::replace(qvalue, "\\\"", "\"")
452 .trim_matches('"')
453 .to_string();
454 return Some(value);
455 }
456 }
457 None
458 }
459}
460
461#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
462#[derive(Debug, Clone)]
463pub struct Fields {
464 fields: Vec<FieldInfo>,
465}
466
467impl Fields {
468 #[inline]
469 pub fn new(fields: Vec<FieldInfo>) -> Fields {
470 Fields { fields }
471 }
472
473 #[inline]
474 pub fn infos(&self) -> &[FieldInfo] {
475 self.fields.as_ref()
476 }
477
478 #[inline]
479 pub fn get<'a, 'b: 'a>(&'a self, indices: &[usize], metas: &'b MetadataObjs) -> &'a FieldInfo {
480 debug_assert!(indices.len() > 0);
481 if indices.len() == 1 {
482 self.get_non_embedded(indices[0])
483 } else {
484 metas[self.fields[indices[0] as usize].meta.key]
485 .unwrap_named(metas)
486 .as_struct()
487 .get(&indices[1..], metas)
488 }
489 }
490
491 #[inline]
492 pub fn get_non_embedded(&self, index: usize) -> &FieldInfo {
493 &self.fields[index]
494 }
495
496 #[inline]
497 pub fn try_index_by_name(&self, name: &str) -> Option<usize> {
498 for (i, f) in self.fields.iter().enumerate() {
499 if f.name == name {
500 return Some(i);
501 }
502 }
503 None
504 }
505
506 #[inline]
507 pub fn index_by_name(&self, name: &str) -> usize {
508 self.try_index_by_name(name).unwrap()
509 }
510
511 #[inline]
512 pub fn indices_by_name(&self, name: &str) -> Vec<usize> {
513 let index = self.index_by_name(name);
514 match &self.fields[index].embedded_indices {
515 Some(indices) => indices.clone(),
516 None => vec![index],
517 }
518 }
519
520 #[inline]
521 pub fn identical(&self, other: &Self, metas: &MetadataObjs) -> bool {
522 if self.fields.len() != other.fields.len() {
523 return false;
524 }
525 for (i, f) in self.fields.iter().enumerate() {
526 let other_f = &other.fields[i];
527 let ok = f.name == other_f.name
528 && f.embedded_indices == other_f.embedded_indices
529 && f.meta.identical(&other_f.meta, metas);
530 if !ok {
531 return false;
532 }
533 }
534 true
535 }
536}
537
538#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
539#[derive(Debug, Clone, Copy)]
540pub struct MethodDesc {
541 pub pointer_recv: bool,
542 pub func: Option<FunctionKey>,
543}
544
545#[derive(Debug, Clone)]
546pub struct Methods {
547 pub members: Vec<Rc<RefCell<MethodDesc>>>,
548 pub mapping: Map<String, OpIndex>,
549}
550
551impl Methods {
552 pub fn new() -> Methods {
553 Methods {
554 members: vec![],
555 mapping: Map::new(),
556 }
557 }
558}
559
560#[cfg(feature = "serde_borsh")]
561impl BorshSerialize for Methods {
562 fn serialize<W: BorshWrite>(&self, writer: &mut W) -> BorshResult<()> {
563 let methods: Vec<MethodDesc> = self.members.iter().map(|x| *x.borrow()).collect();
564 methods.serialize(writer)?;
565 self.mapping.serialize(writer)
566 }
567}
568
569#[cfg(feature = "serde_borsh")]
570impl BorshDeserialize for Methods {
571 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> BorshResult<Self> {
572 let methods = Vec::<MethodDesc>::deserialize_reader(reader)?;
573 let members = methods
574 .into_iter()
575 .map(|x| Rc::new(RefCell::new(x)))
576 .collect();
577 let mapping = Map::<String, OpIndex>::deserialize_reader(reader)?;
578 Ok(Methods { members, mapping })
579 }
580}
581
582#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
583#[derive(Debug, Clone)]
584pub struct SigMetadata {
585 pub recv: Option<Meta>,
586 pub params: Vec<Meta>,
587 pub results: Vec<Meta>,
588 pub variadic: Option<(Meta, Meta)>,
589 pub params_type: Vec<ValueType>, }
591
592impl Default for SigMetadata {
593 fn default() -> SigMetadata {
594 Self {
595 recv: None,
596 params: vec![],
597 results: vec![],
598 variadic: None,
599 params_type: vec![],
600 }
601 }
602}
603
604impl SigMetadata {
605 pub fn pointer_recv(&self) -> bool {
606 match &self.recv {
607 Some(r) => r.ptr_depth > 0,
608 None => false,
609 }
610 }
611
612 pub fn identical(&self, other: &Self, metas: &MetadataObjs) -> bool {
613 if !match (&self.recv, &other.recv) {
614 (None, None) => true,
615 (Some(a), Some(b)) => a.identical(b, metas),
616 _ => false,
617 } {
618 return false;
619 }
620 if self.params.len() != other.params.len() {
621 return false;
622 }
623 for (i, p) in self.params.iter().enumerate() {
624 if !p.identical(&other.params[i], metas) {
625 return false;
626 }
627 }
628 if self.results.len() != other.results.len() {
629 return false;
630 }
631 for (i, r) in self.results.iter().enumerate() {
632 if !r.identical(&other.results[i], metas) {
633 return false;
634 }
635 }
636 if !match (&self.variadic, &other.variadic) {
637 (None, None) => true,
638 (Some((a, _)), Some((b, _))) => a.identical(b, metas),
639 _ => false,
640 } {
641 return false;
642 }
643 true
644 }
645}
646
647#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
648#[derive(Debug, Clone)]
649pub enum MetadataType {
650 Bool,
651 Int,
652 Int8,
653 Int16,
654 Int32,
655 Int64,
656 Uint,
657 UintPtr,
658 Uint8,
659 Uint16,
660 Uint32,
661 Uint64,
662 Float32,
663 Float64,
664 Complex64,
665 Complex128,
666 UnsafePtr,
667 Str,
668 Array(Meta, usize),
669 Slice(Meta),
670 Struct(Fields),
671 Signature(SigMetadata),
672 Map(Meta, Meta),
673 Interface(Fields),
674 Channel(ChannelType, Meta),
675 Named(Methods, Meta),
676 None,
677}
678
679impl MetadataType {
680 #[inline]
681 pub fn as_signature(&self) -> &SigMetadata {
682 match self {
683 Self::Signature(s) => s,
684 _ => unreachable!(),
685 }
686 }
687
688 #[inline]
689 pub fn as_interface(&self) -> &Fields {
690 match self {
691 Self::Interface(fields) => fields,
692 _ => unreachable!(),
693 }
694 }
695
696 #[inline]
697 pub fn as_channel(&self) -> (&ChannelType, &Meta) {
698 match self {
699 Self::Channel(t, m) => (t, m),
700 _ => unreachable!(),
701 }
702 }
703
704 #[inline]
705 pub fn as_array(&self) -> (&Meta, &usize) {
706 match self {
707 Self::Array(m, s) => (m, s),
708 _ => unreachable!(),
709 }
710 }
711
712 #[inline]
713 pub fn as_slice(&self) -> &Meta {
714 match self {
715 Self::Slice(m) => m,
716 _ => unreachable!(),
717 }
718 }
719
720 #[inline]
721 pub fn as_map(&self) -> (&Meta, &Meta) {
722 match self {
723 Self::Map(k, v) => (k, v),
724 _ => unreachable!(),
725 }
726 }
727
728 #[inline]
729 pub fn as_struct(&self) -> &Fields {
730 match self {
731 Self::Struct(f) => f,
732 _ => unreachable!(),
733 }
734 }
735
736 #[inline]
737 pub fn as_named(&self) -> (&Methods, &Meta) {
738 match self {
739 Self::Named(meth, meta) => (meth, meta),
740 _ => unreachable!(),
741 }
742 }
743
744 #[inline]
745 pub fn as_named_mut(&mut self) -> (&mut Methods, &mut Meta) {
746 match self {
747 Self::Named(meth, meta) => (meth, meta),
748 _ => unreachable!(),
749 }
750 }
751
752 #[inline]
753 pub fn unwrap_named<'a, 'b: 'a>(&'a self, metas: &'b MetadataObjs) -> &'a Self {
754 match self {
755 Self::Named(_, meta) => &metas[meta.key],
756 _ => self,
757 }
758 }
759
760 pub fn identical(&self, other: &Self, metas: &MetadataObjs) -> bool {
761 match (self, other) {
762 (Self::Bool, Self::Bool) => true,
763 (Self::Int, Self::Int) => true,
764 (Self::Int8, Self::Int8) => true,
765 (Self::Int16, Self::Int16) => true,
766 (Self::Int32, Self::Int32) => true,
767 (Self::Int64, Self::Int64) => true,
768 (Self::Uint8, Self::Uint8) => true,
769 (Self::Uint16, Self::Uint16) => true,
770 (Self::Uint32, Self::Uint32) => true,
771 (Self::Uint64, Self::Uint64) => true,
772 (Self::Float32, Self::Float32) => true,
773 (Self::Float64, Self::Float64) => true,
774 (Self::Complex64, Self::Complex64) => true,
775 (Self::Complex128, Self::Complex128) => true,
776 (Self::Str, Self::Str) => true,
777 (Self::Struct(a), Self::Struct(b)) => a.identical(b, metas),
778 (Self::Signature(a), Self::Signature(b)) => a.identical(b, metas),
779 (Self::Array(a, size_a), Self::Array(b, size_b)) => {
780 size_a == size_b && a.identical(b, metas)
781 }
782 (Self::Slice(a), Self::Slice(b)) => a.identical(b, metas),
783 (Self::Map(ak, av), Self::Map(bk, bv)) => {
784 ak.identical(bk, metas) && av.identical(bv, metas)
785 }
786 (Self::Interface(a), Self::Interface(b)) => a.identical(b, metas),
787 (Self::Channel(at, avt), Self::Channel(bt, bvt)) => {
788 at == bt && avt.identical(bvt, metas)
789 }
790 (Self::Named(_, a), Self::Named(_, b)) => a.identical(b, metas),
791 _ => false,
792 }
793 }
794}