1use crate::{
2 global::{
3 operators::AssignmentOperator,
4 type_instruction_codes::TypeReferenceMutabilityCode,
5 },
6 values::core_values::{
7 decimal::{Decimal, utils::decimal_to_string},
8 endpoint::{Endpoint, EndpointParsingError},
9 integer::Integer,
10 },
11};
12
13use crate::{
14 global::type_instruction_codes::{TypeLocalOrShared, TypeMutabilityCode},
15 prelude::*,
16 shared_values::pointer_address::{
17 PointerAddress, ReferencedPointerAddress,
18 },
19 values::core_values::r#type::TypeMetadata,
20};
21use binrw::{BinRead, BinWrite};
22use core::{fmt::Display, prelude::rust_2024::*};
23use modular_bitfield::{bitfield, specifiers::B4};
24use serde::{Deserialize, Serialize};
25
26#[derive(Clone, Debug, PartialEq)]
27pub enum Instruction {
28 RegularInstruction(RegularInstruction),
30 TypeInstruction(TypeInstruction),
32}
33
34impl Display for Instruction {
35 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36 match self {
37 Instruction::RegularInstruction(instr) => {
38 core::write!(f, "{}", instr)
39 }
40 Instruction::TypeInstruction(instr) => {
41 core::write!(f, "TYPE_INSTRUCTION {}", instr)
42 }
43 }
44 }
45}
46
47impl From<RegularInstruction> for Instruction {
48 fn from(instruction: RegularInstruction) -> Self {
49 Instruction::RegularInstruction(instruction)
50 }
51}
52
53impl From<TypeInstruction> for Instruction {
54 fn from(instruction: TypeInstruction) -> Self {
55 Instruction::TypeInstruction(instruction)
56 }
57}
58
59#[derive(Clone, Debug, PartialEq)]
60pub enum RegularInstruction {
61 Int8(Int8Data),
63 Int16(Int16Data),
64 Int32(Int32Data),
65 Int64(Int64Data),
66 Int128(Int128Data),
67
68 UInt8(UInt8Data),
70 UInt16(UInt16Data),
71 UInt32(UInt32Data),
72 UInt64(UInt64Data),
73 UInt128(UInt128Data),
74
75 BigInteger(IntegerData),
77
78 Integer(IntegerData),
80 Range,
81
82 Endpoint(Endpoint),
83
84 DecimalF32(Float32Data),
85 DecimalF64(Float64Data),
86 DecimalAsInt16(FloatAsInt16Data),
87 DecimalAsInt32(FloatAsInt32Data),
88 BigDecimal(DecimalData),
89 Decimal(DecimalData),
91
92 RemoteExecution(InstructionBlockData),
93
94 ShortText(ShortTextData),
95 Text(TextData),
96 True,
97 False,
98 Null,
99 Statements(StatementsData),
100 ShortStatements(StatementsData),
101 UnboundedStatements,
102 UnboundedStatementsEnd(bool),
103 List(ListData),
104 ShortList(ListData),
105 Map(MapData),
106 ShortMap(MapData),
107
108 KeyValueDynamic,
109 KeyValueShortText(ShortTextData),
110
111 Add,
113 Subtract,
114 Multiply,
115 Divide,
116
117 UnaryMinus,
120 UnaryPlus,
122 BitwiseNot,
123
124 Apply(ApplyData),
125
126 GetPropertyText(ShortTextData),
127 SetPropertyText(ShortTextData),
128 SetPropertyDynamic,
129
130 GetPropertyIndex(UInt32Data),
131 SetPropertyIndex(UInt32Data),
132 GetPropertyDynamic,
133
134 Is,
136 Matches,
137 StructuralEqual,
138 Equal,
139 NotStructuralEqual,
140 NotEqual,
141
142 AddAssign(SlotAddress),
144 SubtractAssign(SlotAddress),
145 MultiplyAssign(SlotAddress),
146 DivideAssign(SlotAddress),
147
148 CreateSharedReference,
149
150 CreateShared,
151 CreateSharedMut,
152
153 GetSharedRef(RawRemotePointerAddress),
155 GetSharedRefMut(RawRemotePointerAddress),
157 GetLocalRef(RawLocalPointerAddress),
158 GetInternalRef(RawInternalPointerAddress),
159
160 GetOrCreateRef(GetOrCreateRemoteRefData),
162 GetOrCreateRefMut(GetOrCreateRemoteRefData),
164
165 AllocateSlot(SlotAddress),
166 GetSlot(SlotAddress),
167 DropSlot(SlotAddress),
168 SetSlot(SlotAddress),
169
170 GetInternalSlot(SlotAddress),
171
172 SetReferenceValue(AssignmentOperator),
173 Unbox,
174
175 TypedValue,
176 TypeExpression,
177}
178
179impl Display for RegularInstruction {
180 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
181 match self {
182 RegularInstruction::Int8(data) => {
183 core::write!(f, "INT_8 {}", data.0)
184 }
185 RegularInstruction::Int16(data) => {
186 core::write!(f, "INT_16 {}", data.0)
187 }
188 RegularInstruction::Int32(data) => {
189 core::write!(f, "INT_32 {}", data.0)
190 }
191 RegularInstruction::Int64(data) => {
192 core::write!(f, "INT_64 {}", data.0)
193 }
194 RegularInstruction::Int128(data) => {
195 core::write!(f, "INT_128 {}", data.0)
196 }
197
198 RegularInstruction::UInt8(data) => {
199 core::write!(f, "UINT_8 {}", data.0)
200 }
201 RegularInstruction::UInt16(data) => {
202 core::write!(f, "UINT_16 {}", data.0)
203 }
204 RegularInstruction::UInt32(data) => {
205 core::write!(f, "UINT_32 {}", data.0)
206 }
207 RegularInstruction::UInt64(data) => {
208 core::write!(f, "UINT_64 {}", data.0)
209 }
210 RegularInstruction::UInt128(data) => {
211 core::write!(f, "UINT_128 {}", data.0)
212 }
213 RegularInstruction::Range => {
214 core::write!(f, "RANGE regular instruction")
215 }
216 RegularInstruction::Apply(count) => {
217 core::write!(f, "APPLY {}", count.arg_count)
218 }
219 RegularInstruction::BigInteger(data) => {
220 core::write!(f, "BIG_INTEGER {}", data.0)
221 }
222 RegularInstruction::Integer(data) => {
223 core::write!(f, "INTEGER {}", data.0)
224 }
225 RegularInstruction::Endpoint(data) => {
226 core::write!(f, "ENDPOINT {data}")
227 }
228
229 RegularInstruction::DecimalAsInt16(data) => {
230 core::write!(f, "DECIMAL_AS_INT_16 {}", data.0)
231 }
232 RegularInstruction::DecimalAsInt32(data) => {
233 core::write!(f, "DECIMAL_AS_INT_32 {}", data.0)
234 }
235 RegularInstruction::DecimalF32(data) => {
236 core::write!(
237 f,
238 "DECIMAL_F32 {}",
239 decimal_to_string(data.0, false)
240 )
241 }
242 RegularInstruction::DecimalF64(data) => {
243 core::write!(
244 f,
245 "DECIMAL_F64 {}",
246 decimal_to_string(data.0, false)
247 )
248 }
249 RegularInstruction::BigDecimal(data) => {
250 core::write!(f, "DECIMAL_BIG {}", data.0)
251 }
252 RegularInstruction::Decimal(data) => {
253 core::write!(f, "DECIMAL {}", data.0)
254 }
255 RegularInstruction::ShortText(data) => {
256 core::write!(f, "SHORT_TEXT {}", data.0)
257 }
258 RegularInstruction::Text(data) => {
259 core::write!(f, "TEXT {}", data.0)
260 }
261 RegularInstruction::True => core::write!(f, "TRUE"),
262 RegularInstruction::False => core::write!(f, "FALSE"),
263 RegularInstruction::Null => core::write!(f, "NULL"),
264 RegularInstruction::Statements(data) => {
265 core::write!(f, "STATEMENTS {}", data.statements_count)
266 }
267 RegularInstruction::ShortStatements(data) => {
268 core::write!(f, "SHORT_STATEMENTS {}", data.statements_count)
269 }
270 RegularInstruction::UnboundedStatements => {
271 core::write!(f, "UNBOUNDED_STATEMENTS")
272 }
273 RegularInstruction::UnboundedStatementsEnd(_) => {
274 core::write!(f, "STATEMENTS_END")
275 }
276 RegularInstruction::List(data) => {
277 core::write!(f, "LIST {}", data.element_count)
278 }
279 RegularInstruction::ShortList(data) => {
280 core::write!(f, "SHORT_LIST {}", data.element_count)
281 }
282 RegularInstruction::Map(data) => {
283 core::write!(f, "MAP {}", data.element_count)
284 }
285 RegularInstruction::ShortMap(data) => {
286 core::write!(f, "SHORT_MAP {}", data.element_count)
287 }
288 RegularInstruction::KeyValueDynamic => {
289 core::write!(f, "KEY_VALUE_DYNAMIC")
290 }
291 RegularInstruction::KeyValueShortText(data) => {
292 core::write!(f, "KEY_VALUE_SHORT_TEXT {}", data.0)
293 }
294 RegularInstruction::Add => core::write!(f, "ADD"),
296 RegularInstruction::Subtract => core::write!(f, "SUBTRACT"),
297 RegularInstruction::Multiply => core::write!(f, "MULTIPLY"),
298 RegularInstruction::Divide => core::write!(f, "DIVIDE"),
299
300 RegularInstruction::StructuralEqual => {
302 core::write!(f, "STRUCTURAL_EQUAL")
303 }
304 RegularInstruction::Equal => core::write!(f, "EQUAL"),
305 RegularInstruction::NotStructuralEqual => {
306 core::write!(f, "NOT_STRUCTURAL_EQUAL")
307 }
308 RegularInstruction::NotEqual => core::write!(f, "NOT_EQUAL"),
309 RegularInstruction::Is => core::write!(f, "IS"),
310 RegularInstruction::Matches => core::write!(f, "MATCHES"),
311
312 RegularInstruction::AllocateSlot(address) => {
313 core::write!(f, "ALLOCATE_SLOT {}", address.0)
314 }
315 RegularInstruction::GetSlot(address) => {
316 core::write!(f, "GET_SLOT {}", address.0)
317 }
318 RegularInstruction::GetInternalSlot(address) => {
319 core::write!(f, "GET_INTERNAL_SLOT {}", address.0)
320 }
321 RegularInstruction::DropSlot(address) => {
322 core::write!(f, "DROP_SLOT {}", address.0)
323 }
324 RegularInstruction::SetSlot(address) => {
325 core::write!(f, "SET_SLOT {}", address.0)
326 }
327 RegularInstruction::SetReferenceValue(operator) => {
328 core::write!(f, "SET_REFERENCE_VALUE ({})", operator)
329 }
330 RegularInstruction::Unbox => core::write!(f, "UNBOX"),
331 RegularInstruction::GetSharedRef(address) => {
332 core::write!(
333 f,
334 "GET_SHARED_REF [{}:{}]",
335 address.endpoint().expect("Invalid endpoint"),
336 hex::encode(address.id)
337 )
338 }
339 RegularInstruction::GetSharedRefMut(address) => {
340 core::write!(
341 f,
342 "GET_SHARED_REF_MUT [{}:{}]",
343 address.endpoint().expect("Invalid endpoint"),
344 hex::encode(address.id)
345 )
346 }
347 RegularInstruction::GetLocalRef(address) => {
348 core::write!(
349 f,
350 "GET_LOCAL_REF [origin_id: {}]",
351 hex::encode(address.id)
352 )
353 }
354 RegularInstruction::GetInternalRef(address) => {
355 core::write!(
356 f,
357 "GET_INTERNAL_REF [internal_id: {}]",
358 hex::encode(address.id)
359 )
360 }
361 RegularInstruction::CreateSharedReference => {
362 core::write!(f, "CREATE_SHARED_REF")
363 }
364 RegularInstruction::CreateShared => {
365 core::write!(f, "CREATE_SHARED")
366 }
367 RegularInstruction::CreateSharedMut => {
368 core::write!(f, "CREATE_SHARED_MUT")
369 }
370 RegularInstruction::GetOrCreateRef(data) => {
371 core::write!(
372 f,
373 "GET_OR_CREATE_REF [{}, block_size: {}]",
374 hex::encode(data.address.id),
375 data.create_block_size
376 )
377 }
378 RegularInstruction::GetOrCreateRefMut(data) => {
379 core::write!(
380 f,
381 "GET_OR_CREATE_REF_MUT [{}, block_size: {}]",
382 hex::encode(data.address.id),
383 data.create_block_size
384 )
385 }
386 RegularInstruction::RemoteExecution(block) => {
387 core::write!(
388 f,
389 "REMOTE_EXECUTION (length: {}, injected_slot_count: {})",
390 block.length,
391 block.injected_slot_count
392 )
393 }
394 RegularInstruction::AddAssign(address) => {
395 core::write!(f, "ADD_ASSIGN {}", address.0)
396 }
397 RegularInstruction::SubtractAssign(address) => {
398 core::write!(f, "SUBTRACT_ASSIGN {}", address.0)
399 }
400 RegularInstruction::MultiplyAssign(address) => {
401 core::write!(f, "MULTIPLY_ASSIGN {}", address.0)
402 }
403 RegularInstruction::DivideAssign(address) => {
404 core::write!(f, "DIVIDE_ASSIGN {}", address.0)
405 }
406 RegularInstruction::UnaryMinus => core::write!(f, "-"),
407 RegularInstruction::UnaryPlus => core::write!(f, "+"),
408 RegularInstruction::BitwiseNot => core::write!(f, "BITWISE_NOT"),
409 RegularInstruction::TypedValue => core::write!(f, "TYPED_VALUE"),
410 RegularInstruction::TypeExpression => {
411 core::write!(f, "TYPE_EXPRESSION")
412 }
413 RegularInstruction::GetPropertyIndex(uint_32_data) => {
414 core::write!(f, "GET_PROPERTY_INDEX {}", uint_32_data.0)
415 }
416 RegularInstruction::SetPropertyIndex(uint_32_data) => {
417 core::write!(f, "SET_PROPERTY_INDEX {}", uint_32_data.0)
418 }
419 RegularInstruction::GetPropertyText(short_text_data) => {
420 core::write!(f, "GET_PROPERTY_TEXT {}", short_text_data.0)
421 }
422 RegularInstruction::SetPropertyText(short_text_data) => {
423 core::write!(f, "SET_PROPERTY_TEXT {}", short_text_data.0)
424 }
425 RegularInstruction::GetPropertyDynamic => {
426 core::write!(f, "GET_PROPERTY_DYNAMIC")
427 }
428 RegularInstruction::SetPropertyDynamic => {
429 core::write!(f, "SET_PROPERTY_DYNAMIC")
430 }
431 }
432 }
433}
434
435#[derive(Clone, Debug, PartialEq)]
436pub enum TypeInstruction {
437 ImplType(ImplTypeData),
438 SharedTypeReference(TypeReferenceData),
439 LiteralText(TextData),
440 LiteralInteger(IntegerData),
441 List(ListData),
442 Range, }
444
445impl Display for TypeInstruction {
446 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
447 match self {
448 TypeInstruction::LiteralText(data) => {
449 core::write!(f, "LITERAL_TEXT {}", data.0)
450 }
451 TypeInstruction::LiteralInteger(data) => {
452 core::write!(f, "LITERAL_INTEGER {}", data.0)
453 }
454 TypeInstruction::List(data) => {
455 core::write!(f, "LIST {}", data.element_count)
456 }
457 TypeInstruction::SharedTypeReference(reference_data) => {
458 core::write!(
459 f,
460 "TYPE_REFERENCE mutability: {:?}, address: {}",
461 TypeMetadata::from(&reference_data.metadata),
462 PointerAddress::from(&reference_data.address)
463 )
464 }
465 TypeInstruction::ImplType(data) => {
466 core::write!(f, "IMPL_TYPE ({} impls)", data.impl_count)
467 }
468 TypeInstruction::Range => {
469 core::write!(f, "Range type instruction")
470 }
471 }
472 }
473}
474
475#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
476#[brw(little)]
477pub struct Int8Data(pub i8);
478
479#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
480#[brw(little)]
481pub struct Int16Data(pub i16);
482
483#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
484#[brw(little)]
485pub struct Int32Data(pub i32);
486
487#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
488#[brw(little)]
489pub struct Int64Data(pub i64);
490
491#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
492#[brw(little)]
493pub struct Int128Data(pub i128);
494
495#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
496#[brw(little)]
497pub struct UInt8Data(pub u8);
498
499#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
500#[brw(little)]
501pub struct UInt16Data(pub u16);
502
503#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
504#[brw(little)]
505pub struct UInt32Data(pub u32);
506
507#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
508#[brw(little)]
509pub struct UInt64Data(pub u64);
510
511#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
512#[brw(little)]
513pub struct UInt128Data(pub u128);
514
515#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
516#[brw(little)]
517pub struct Float32Data(pub f32);
518
519#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
520#[brw(little)]
521pub struct Float64Data(pub f64);
522
523#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
524#[brw(little)]
525pub struct FloatAsInt16Data(pub i16);
526
527#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
528#[brw(little)]
529pub struct FloatAsInt32Data(pub i32);
530
531#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
532#[brw(little)]
533pub struct DecimalData(pub Decimal);
534
535#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
536#[brw(little)]
537pub struct IntegerData(pub Integer);
538
539#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
540#[brw(little)]
541pub struct ShortTextDataRaw {
542 pub length: u8,
543 #[br(count = length)]
544 pub text: Vec<u8>,
545}
546
547#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
548#[brw(little)]
549pub struct TextDataRaw {
550 pub length: u32,
551 #[br(count = length)]
552 pub text: Vec<u8>,
553}
554
555#[derive(Clone, Debug, PartialEq)]
556pub struct ShortTextData(pub String);
557
558#[derive(Clone, Debug, PartialEq)]
559pub struct TextData(pub String);
560
561#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
562#[brw(little)]
563pub struct ShortListData {
564 pub element_count: u8,
565}
566
567#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
568#[brw(little)]
569pub struct StatementsData {
570 pub statements_count: u32,
571 #[br(map = |x: u8| x != 0)]
572 #[bw(map = |b: &bool| if *b { 1u8 } else { 0u8 })]
573 pub terminated: bool,
574}
575
576#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
577#[brw(little)]
578pub struct UnboundedStatementsData {
579 #[br(map = |x: u8| x != 0)]
580 #[bw(map = |b: &bool| if *b { 1u8 } else { 0u8 })]
581 pub terminated: bool,
582}
583
584#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
585#[brw(little)]
586pub struct ShortStatementsData {
587 pub statements_count: u8,
588 #[br(map = |x: u8| x != 0)]
589 #[bw(map = |b: &bool| if *b { 1u8 } else { 0u8 })]
590 pub terminated: bool,
591}
592
593#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
594#[brw(little)]
595pub struct ListData {
596 pub element_count: u32,
597}
598
599#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
600#[brw(little)]
601pub struct ShortMapData {
602 pub element_count: u8,
603}
604
605#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
606#[brw(little)]
607pub struct MapData {
608 pub element_count: u32,
609}
610
611#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
612#[brw(little)]
613pub struct InstructionCloseAndStore {
614 pub instruction: Int8Data,
615}
616
617#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
618#[brw(little)]
619pub struct SlotAddress(pub u32);
620
621#[derive(
622 BinRead, BinWrite, Clone, Debug, PartialEq, Serialize, Deserialize,
623)]
624#[brw(little)]
625pub struct RawRemotePointerAddress {
626 pub id: [u8; 26],
627}
628impl RawRemotePointerAddress {
629 pub fn endpoint(&self) -> Result<Endpoint, EndpointParsingError> {
630 let mut endpoint = [0u8; 21];
631 endpoint.copy_from_slice(&self.id[0..21]);
632 Endpoint::from_slice(endpoint)
633 }
634}
635
636#[derive(Debug, Clone, PartialEq)]
637pub struct PointerAddressConversionError;
638
639impl TryFrom<PointerAddress> for RawRemotePointerAddress {
640 type Error = PointerAddressConversionError;
641 fn try_from(ptr: PointerAddress) -> Result<Self, Self::Error> {
642 match ptr {
643 PointerAddress::Referenced(ReferencedPointerAddress::Remote(
644 bytes,
645 )) => Ok(RawRemotePointerAddress { id: bytes }),
646 _ => Err(PointerAddressConversionError),
647 }
648 }
649}
650
651#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
652#[brw(little)]
653pub struct RawLocalPointerAddress {
654 pub id: [u8; 5],
655}
656
657#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
658#[brw(little)]
659pub struct RawInternalPointerAddress {
660 pub id: [u8; 3],
661}
662
663#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
664#[brw(little)]
665pub enum RawPointerAddress {
666 #[br(magic = 120u8)] Remote(RawRemotePointerAddress),
668 #[br(magic = 121u8)] Internal(RawInternalPointerAddress),
670 #[br(magic = 122u8)] Local(RawLocalPointerAddress),
672}
673
674#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
675#[brw(little)]
676pub struct GetOrCreateRemoteRefData {
677 pub address: RawRemotePointerAddress,
678 pub create_block_size: u64,
679}
680
681#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
682#[brw(little)]
683pub struct InstructionBlockData {
684 pub length: u32,
685 pub injected_slot_count: u32,
686 #[br(count = injected_slot_count)]
687 pub injected_slots: Vec<u32>,
688 #[br(count = length)]
689 pub body: Vec<u8>,
690}
691
692#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
693#[brw(little)]
694pub struct ApplyData {
695 pub arg_count: u16,
696}
697
698#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
699#[brw(little)]
700pub struct ImplTypeData {
701 pub metadata: TypeMetadataBin,
702 pub impl_count: u8,
703 #[br(count = impl_count)]
704 pub impls: Vec<RawPointerAddress>,
705}
706
707#[derive(BinRead, BinWrite, Clone, Debug, PartialEq)]
708#[brw(little)]
709pub struct TypeReferenceData {
710 pub metadata: TypeMetadataBin,
711 pub address: RawPointerAddress,
712}
713
714#[bitfield]
715#[derive(BinWrite, BinRead, Clone, Copy, Debug, PartialEq)]
716#[bw(map = |&x| Self::into_bytes(x))]
717#[br(map = Self::from_bytes)]
718#[brw(little)]
719pub struct TypeMetadataBin {
720 pub reference_mutability: TypeReferenceMutabilityCode,
721 pub mutability: TypeMutabilityCode,
722 pub type_local_or_shared: TypeLocalOrShared,
723 _unused: B4,
724}
725
726impl From<&TypeMetadataBin> for TypeMetadata {
727 fn from(value: &TypeMetadataBin) -> Self {
728 match value.type_local_or_shared() {
729 TypeLocalOrShared::Local => TypeMetadata::Local {
730 mutability: (&value.mutability()).into(),
731 reference_mutability: (&value.reference_mutability()).into(),
732 },
733 TypeLocalOrShared::Shared => TypeMetadata::Shared {
734 mutability: (&value.mutability()).into(),
735 reference_mutability: (&value.reference_mutability()).into(),
736 },
737 }
738 }
739}
740
741impl From<&TypeMetadata> for TypeMetadataBin {
742 fn from(value: &TypeMetadata) -> Self {
743 match value {
744 TypeMetadata::Local {
745 mutability,
746 reference_mutability,
747 } => Self::new()
748 .with_type_local_or_shared(TypeLocalOrShared::Local)
749 .with_mutability(mutability.into())
750 .with_reference_mutability(reference_mutability.into()),
751 TypeMetadata::Shared {
752 mutability,
753 reference_mutability,
754 } => Self::new()
755 .with_type_local_or_shared(TypeLocalOrShared::Shared)
756 .with_mutability(mutability.into())
757 .with_reference_mutability(reference_mutability.into()),
758 }
759 }
760}