Skip to main content

hyperlight_common/func/
param_type.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025 The Hyperlight Authors.
3
4use alloc::string::String;
5use alloc::vec;
6use alloc::vec::Vec;
7
8use super::error::Error;
9use super::utils::for_each_tuple;
10use crate::flatbuffer_wrappers::function_types::{ParameterType, ParameterValue};
11
12/// This is a marker trait that is used to indicate that a type is a
13/// valid Hyperlight parameter type.
14///
15/// For each parameter type Hyperlight supports in host functions, we
16/// provide an implementation for `SupportedParameterType`
17pub trait SupportedParameterType: Sized + Clone + Send + Sync + 'static {
18    /// The underlying Hyperlight parameter type representing this `SupportedParameterType`
19    const TYPE: ParameterType;
20
21    /// Get the underling Hyperlight parameter value representing this
22    /// `SupportedParameterType`
23    fn into_value(self) -> ParameterValue;
24    /// Get the actual inner value of this `SupportedParameterType`
25    fn from_value(value: ParameterValue) -> Result<Self, Error>;
26}
27
28// We can then implement these traits for each type that Hyperlight supports as a parameter or return type
29macro_rules! for_each_param_type {
30    ($macro:ident) => {
31        $macro!(String, String);
32        $macro!(i32, Int);
33        $macro!(u32, UInt);
34        $macro!(i64, Long);
35        $macro!(u64, ULong);
36        $macro!(f32, Float);
37        $macro!(f64, Double);
38        $macro!(bool, Bool);
39        $macro!(Vec<u8>, VecBytes);
40    };
41}
42
43macro_rules! impl_supported_param_type {
44    ($type:ty, $enum:ident) => {
45        impl SupportedParameterType for $type {
46            const TYPE: ParameterType = ParameterType::$enum;
47
48            fn into_value(self) -> ParameterValue {
49                ParameterValue::$enum(self)
50            }
51
52            fn from_value(value: ParameterValue) -> Result<Self, Error> {
53                match value {
54                    ParameterValue::$enum(i) => Ok(i),
55                    other => Err(Error::ParameterValueConversionFailure(
56                        other.clone(),
57                        stringify!($type),
58                    )),
59                }
60            }
61        }
62    };
63}
64
65for_each_param_type!(impl_supported_param_type);
66
67/// A trait to describe the tuple of parameters that a host function can take.
68pub trait ParameterTuple: Sized + Clone + Send + Sync + 'static {
69    /// The number of parameters in the tuple
70    const SIZE: usize;
71
72    /// The underlying Hyperlight parameter types representing this tuple of `SupportedParameterType`
73    const TYPE: &[ParameterType];
74
75    /// Get the underling Hyperlight parameter value representing this
76    /// `SupportedParameterType`
77    fn into_value(self) -> Vec<ParameterValue>;
78
79    /// Get the actual inner value of this `SupportedParameterType`
80    fn from_value(value: Vec<ParameterValue>) -> Result<Self, Error>;
81}
82
83impl<T: SupportedParameterType> ParameterTuple for T {
84    const SIZE: usize = 1;
85
86    const TYPE: &[ParameterType] = &[T::TYPE];
87
88    fn into_value(self) -> Vec<ParameterValue> {
89        vec![self.into_value()]
90    }
91
92    fn from_value(value: Vec<ParameterValue>) -> Result<Self, Error> {
93        match <[ParameterValue; 1]>::try_from(value) {
94            Ok([val]) => Ok(T::from_value(val)?),
95            Err(value) => Err(Error::UnexpectedNoOfArguments(value.len(), 1)),
96        }
97    }
98}
99
100macro_rules! impl_param_tuple {
101    ([$N:expr] ($($name:ident: $param:ident),*)) => {
102        impl<$($param: SupportedParameterType),*> ParameterTuple for ($($param,)*) {
103            const SIZE: usize = $N;
104
105            const TYPE: &[ParameterType] = &[
106                $($param::TYPE),*
107            ];
108
109            fn into_value(self) -> Vec<ParameterValue> {
110                let ($($name,)*) = self;
111                vec![$($name.into_value()),*]
112            }
113
114            fn from_value(value: Vec<ParameterValue>) -> Result<Self, Error> {
115                match <[ParameterValue; $N]>::try_from(value) {
116                    Ok([$($name,)*]) => Ok(($($param::from_value($name)?,)*)),
117                    Err(value) => Err(Error::UnexpectedNoOfArguments(value.len(), $N))
118                }
119            }
120        }
121    };
122}
123
124for_each_tuple!(impl_param_tuple);