use rkyv::{Archive, Deserialize, Serialize};
use crate::{
AbiParam, AbiScalarType, AbiScalarValue, AbiSignature, CallPlanError, GuestResourceId,
};
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[rkyv(bytecheck())]
pub enum EntrypointArg {
Scalar(AbiScalarValue),
Buffer(Vec<u8>),
Resource(GuestResourceId),
}
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[rkyv(bytecheck())]
pub struct EntrypointInvocation {
pub signature: AbiSignature,
pub args: Vec<EntrypointArg>,
}
impl EntrypointInvocation {
pub fn new(signature: AbiSignature, args: Vec<EntrypointArg>) -> Result<Self, CallPlanError> {
let invocation = Self { signature, args };
invocation.validate()?;
Ok(invocation)
}
pub fn validate(&self) -> Result<(), CallPlanError> {
if self.signature.params().len() != self.args.len() {
return Err(CallPlanError::ParameterCount {
expected: self.signature.params().len(),
actual: self.args.len(),
});
}
for (index, (param, arg)) in self
.signature
.params()
.iter()
.zip(self.args.iter())
.enumerate()
{
match (param, arg) {
(AbiParam::Scalar(expected), EntrypointArg::Scalar(actual)) => {
if actual.kind() != *expected {
return Err(CallPlanError::ValueMismatch {
index,
reason: "scalar type mismatch",
});
}
}
(AbiParam::Scalar(AbiScalarType::I32), EntrypointArg::Resource(_))
| (AbiParam::Scalar(AbiScalarType::U64), EntrypointArg::Resource(_)) => {}
(AbiParam::Buffer, EntrypointArg::Buffer(_)) => {}
_ => {
return Err(CallPlanError::ValueMismatch {
index,
reason: "argument incompatible with signature",
});
}
}
}
Ok(())
}
pub fn signature(&self) -> &AbiSignature {
&self.signature
}
}
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[rkyv(bytecheck())]
pub struct ProcessLogRegistration {
pub channel: GuestResourceId,
}
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[rkyv(bytecheck())]
pub struct ProcessLogLookup {
pub process_id: GuestResourceId,
}
#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
#[rkyv(bytecheck())]
pub struct ProcessStart {
pub module_id: String,
pub name: String,
pub capabilities: Vec<crate::Capability>,
pub entrypoint: EntrypointInvocation,
}