use concepts::{
ResultParsingError, ResultParsingErrorFromVal, ReturnTypeExtendable,
SupportedFunctionReturnValue, storage::Version,
};
use executor::worker::{FatalError, WorkerError};
pub(crate) fn map_js_ok_to_user_retval(
ok_val: &serde_json::Value,
user_return_type: &ReturnTypeExtendable,
version: Version,
) -> Result<SupportedFunctionReturnValue, WorkerError> {
match &user_return_type.type_wrapper_tl.ok {
Some(configured_ok_type) => {
let wvt =
val_json::wast_val_ser::deserialize_value(ok_val, *configured_ok_type.clone())
.map_err(|err| {
WorkerError::FatalError(
FatalError::ResultParsingError(
ResultParsingError::ResultParsingErrorFromVal(
ResultParsingErrorFromVal::TypeCheckError(format!(
"failed to type check the return value `{ok_val}` as \
`{configured_ok_type}`: {err}"
)),
),
),
version.clone(),
)
})?;
Ok(SupportedFunctionReturnValue::Ok(Some(wvt)))
}
None => {
if *ok_val == serde_json::Value::Null {
Ok(SupportedFunctionReturnValue::Ok(None))
} else {
Err(WorkerError::FatalError(
FatalError::ResultParsingError(ResultParsingError::ResultParsingErrorFromVal(
ResultParsingErrorFromVal::TypeCheckError(format!(
"return value type check failed, expected `null`, got `{ok_val}`"
)),
)),
version,
))
}
}
}
}
pub(crate) fn map_js_throw_to_user_err(
thrown: &str,
user_return_type: &ReturnTypeExtendable,
version: Version,
) -> Result<SupportedFunctionReturnValue, WorkerError> {
let thrown_val: serde_json::Value =
serde_json::from_str(thrown).unwrap_or(serde_json::Value::Null);
match user_return_type.type_wrapper_tl.err.as_deref() {
None => {
if thrown_val == serde_json::Value::Null {
Ok(SupportedFunctionReturnValue::Err(None))
} else {
let declared_return_type = user_return_type.to_string();
Err(WorkerError::FatalError(
FatalError::ResultParsingError(ResultParsingError::ResultParsingErrorFromVal(
ResultParsingErrorFromVal::TypeCheckError(format!(
"thrown value type check failed: return type is `{declared_return_type}` (no error \
type), expected `throw null`, got `{thrown}`"
)),
)),
version,
))
}
}
Some(user_err_type) => {
let wvt = val_json::wast_val_ser::deserialize_value(&thrown_val, user_err_type.clone())
.map_err(|e| {
WorkerError::FatalError(
FatalError::ResultParsingError(
ResultParsingError::ResultParsingErrorFromVal(
ResultParsingErrorFromVal::TypeCheckError(format!(
"failed to type check thrown value `{thrown}` as \
`{user_err_type}`: {e}"
)),
),
),
version.clone(),
)
})?;
Ok(SupportedFunctionReturnValue::Err(Some(wvt)))
}
}
}