linera_witty/primitive_types/
array.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::borrow::Cow;
5
6use crate::{
7    GuestPointer, HList, InstanceWithMemory, Layout, Memory, Runtime, RuntimeError, RuntimeMemory,
8    WitLoad, WitStore, WitType,
9};
10
11impl WitType for [u8; 20] {
12    const SIZE: u32 = <(u64, u64, u64) as WitType>::SIZE;
13    type Layout = <(u64, u64, u64) as WitType>::Layout;
14    type Dependencies = HList![];
15
16    fn wit_type_name() -> Cow<'static, str> {
17        "array20".into()
18    }
19
20    fn wit_type_declaration() -> Cow<'static, str> {
21        concat!(
22            "    record array20 {\n",
23            "        part1: u64,\n",
24            "        part2: u64,\n",
25            "        part3: u64,\n",
26            "    }\n",
27        )
28        .into()
29    }
30}
31
32impl WitLoad for [u8; 20] {
33    fn load<Instance>(
34        memory: &Memory<'_, Instance>,
35        location: GuestPointer,
36    ) -> Result<Self, RuntimeError>
37    where
38        Instance: InstanceWithMemory,
39        <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
40    {
41        let (part1, part2, part3): (u64, u64, u64) = WitLoad::load(memory, location)?;
42        let mut dest = [0u8; 20];
43        dest[0..8].copy_from_slice(&part1.to_be_bytes());
44        dest[8..16].copy_from_slice(&part2.to_be_bytes());
45        dest[16..20].copy_from_slice(&part3.to_be_bytes());
46        Ok(dest)
47    }
48
49    fn lift_from<Instance>(
50        flat_layout: <Self::Layout as crate::Layout>::Flat,
51        memory: &Memory<'_, Instance>,
52    ) -> Result<Self, RuntimeError>
53    where
54        Instance: InstanceWithMemory,
55        <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
56    {
57        let (part1, part2, part3): (u64, u64, u64) = WitLoad::lift_from(flat_layout, memory)?;
58        let mut dest = [0u8; 20];
59        dest[0..8].copy_from_slice(&part1.to_be_bytes());
60        dest[8..16].copy_from_slice(&part2.to_be_bytes());
61        dest[16..20].copy_from_slice(&part3.to_be_bytes());
62        Ok(dest)
63    }
64}
65
66impl WitStore for [u8; 20] {
67    fn store<Instance>(
68        &self,
69        memory: &mut Memory<'_, Instance>,
70        location: GuestPointer,
71    ) -> Result<(), RuntimeError>
72    where
73        Instance: InstanceWithMemory,
74        <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
75    {
76        let part1 = u64::from_be_bytes(self[0..8].try_into().unwrap());
77        let part2 = u64::from_be_bytes(self[8..16].try_into().unwrap());
78        let part3 = u64::from_be_bytes(self[16..20].try_into().unwrap());
79        (part1, part2, part3).store(memory, location)
80    }
81
82    fn lower<Instance>(
83        &self,
84        memory: &mut Memory<'_, Instance>,
85    ) -> Result<<Self::Layout as Layout>::Flat, RuntimeError>
86    where
87        Instance: InstanceWithMemory,
88        <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
89    {
90        let part1 = u64::from_be_bytes(self[0..8].try_into().unwrap());
91        let part2 = u64::from_be_bytes(self[8..16].try_into().unwrap());
92        let part3 = u64::from_be_bytes(self[16..20].try_into().unwrap());
93        (part1, part2, part3).lower(memory)
94    }
95}