iota_types/
layout_resolver.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use iota_sdk_types::{StructTag, TypeTag};
6use move_bytecode_utils::{layout::TypeLayoutBuilder, module_cache::GetModule};
7use move_core_types::annotated_value as A;
8
9use crate::{error::IotaError, iota_sdk_types_conversions::type_tag_sdk_to_core};
10
11pub trait LayoutResolver {
12    fn get_annotated_layout(
13        &mut self,
14        struct_tag: &StructTag,
15    ) -> Result<A::MoveDatatypeLayout, IotaError>;
16}
17
18pub fn get_layout_from_struct_tag(
19    struct_tag: StructTag,
20    resolver: &impl GetModule,
21) -> Result<A::MoveDatatypeLayout, IotaError> {
22    let type_ = TypeTag::Struct(Box::new(struct_tag));
23    let layout = TypeLayoutBuilder::build_with_types(&type_tag_sdk_to_core(&type_), resolver)
24        .map_err(|e| IotaError::ObjectSerialization {
25            error: e.to_string(),
26        })?;
27    match layout {
28        A::MoveTypeLayout::Struct(l) => Ok(A::MoveDatatypeLayout::Struct(l)),
29        A::MoveTypeLayout::Enum(e) => Ok(A::MoveDatatypeLayout::Enum(e)),
30        _ => {
31            unreachable!(
32                "We called get_layout_from_struct_tag on a datatype, should get a datatype layout"
33            )
34        }
35    }
36}
37
38pub fn into_struct_layout(layout: A::MoveDatatypeLayout) -> Result<A::MoveStructLayout, IotaError> {
39    match layout {
40        A::MoveDatatypeLayout::Struct(s) => Ok(*s),
41        A::MoveDatatypeLayout::Enum(e) => Err(IotaError::ObjectSerialization {
42            error: format!("Expected struct layout but got an enum {e:?}"),
43        }),
44    }
45}