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