1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
// Copyright (c) Zefchain Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
//! Representation of the memory layout of complex types as a sequence of fundamental WIT types.
use frunk::{hlist::HList, HCons, HNil};
use super::{element::LayoutElement, FlatLayout};
use crate::primitive_types::MaybeFlatType;
/// Marker trait to prevent [`LayoutElement`] to be implemented for other types.
pub trait Sealed {}
/// Representation of the memory layout of complex types as a sequence of fundamental WIT types.
pub trait Layout: Sealed + HList {
/// The alignment boundary required for the layout.
const ALIGNMENT: u32;
/// Result of flattening this layout.
type Flat: FlatLayout;
/// Flattens this layout into a layout consisting of native WebAssembly types.
///
/// The resulting flat layout does not have any empty items.
fn flatten(self) -> Self::Flat;
}
impl Sealed for HNil {}
impl<Head, Tail> Sealed for HCons<Head, Tail>
where
Head: LayoutElement,
Tail: Layout,
{
}
impl Layout for HNil {
const ALIGNMENT: u32 = 1;
type Flat = HNil;
fn flatten(self) -> Self::Flat {
HNil
}
}
impl<Head, Tail> Layout for HCons<Head, Tail>
where
Head: LayoutElement,
Tail: Layout,
{
const ALIGNMENT: u32 = if Head::ALIGNMENT > Tail::ALIGNMENT {
Head::ALIGNMENT
} else {
Tail::ALIGNMENT
};
type Flat = <Head::Flat as MaybeFlatType>::Flatten<Tail>;
fn flatten(self) -> Self::Flat {
self.head.flatten().flatten(self.tail)
}
}