use concepts::{
ResultParsingError, ResultParsingErrorFromVal, ReturnTypeExtendable,
SupportedFunctionReturnValue, storage::Version,
};
use executor::worker::{FatalError, WorkerError};
use val_json::type_wrapper::TypeWrapper;
pub(crate) fn map_ok_variant(
val: Option<serde_json::Value>,
user_return_type: &ReturnTypeExtendable,
version: Version,
) -> Result<SupportedFunctionReturnValue, WorkerError> {
map_variant(
val,
version,
user_return_type.type_wrapper_tl.ok.as_deref(),
Ok(()),
)
}
pub(crate) fn map_ok_variant_fatal(
val: Option<serde_json::Value>,
user_return_type: &ReturnTypeExtendable,
version: Version,
) -> Result<SupportedFunctionReturnValue, (FatalError, Version)> {
map_variant_fatal(
val,
version,
user_return_type.type_wrapper_tl.ok.as_deref(),
Ok(()),
)
}
pub(crate) fn map_err_variant(
val: Option<serde_json::Value>,
user_return_type: &ReturnTypeExtendable,
version: Version,
) -> Result<SupportedFunctionReturnValue, WorkerError> {
map_variant(
val,
version,
user_return_type.type_wrapper_tl.err.as_deref(),
Err(()),
)
}
pub(crate) fn map_err_variant_fatal(
val: Option<serde_json::Value>,
user_return_type: &ReturnTypeExtendable,
version: Version,
) -> Result<SupportedFunctionReturnValue, (FatalError, Version)> {
map_variant_fatal(
val,
version,
user_return_type.type_wrapper_tl.err.as_deref(),
Err(()),
)
}
fn map_variant(
val: Option<serde_json::Value>,
version: Version,
expected_type: Option<&TypeWrapper>,
variant: Result<(), ()>,
) -> Result<SupportedFunctionReturnValue, WorkerError> {
map_variant_fatal(val, version, expected_type, variant)
.map_err(|(err, version)| WorkerError::FatalError(err, version))
}
fn map_variant_fatal(
val: Option<serde_json::Value>,
version: Version,
expected_type: Option<&TypeWrapper>,
variant: Result<(), ()>,
) -> Result<SupportedFunctionReturnValue, (FatalError, Version)> {
let supported_func = if variant.is_ok() {
SupportedFunctionReturnValue::Ok
} else {
SupportedFunctionReturnValue::Err
};
match (expected_type, val) {
(Some(ty), Some(ok_val)) => {
let wvt =
val_json::wast_val_ser::deserialize_value(&ok_val, ty.clone())
.map_err(|err| {
(
FatalError::ResultParsingError(
ResultParsingError::ResultParsingErrorFromVal(
ResultParsingErrorFromVal::TypeCheckError(format!(
"failed to type check the {variant} variant value `{ok_val}` as type {ty} - {err}",
variant = if variant.is_ok() { "ok" } else { "err" }
)),
),
),
version.clone(),
)
})?;
Ok(supported_func(Some(wvt)))
}
(None, _) => Ok(supported_func(None)), (Some(ty), val) => Err((
FatalError::ResultParsingError(ResultParsingError::ResultParsingErrorFromVal(
ResultParsingErrorFromVal::TypeCheckError(format!(
"failed to type check the {variant} variant `{val} as type {ty}",
variant = if variant.is_ok() { "ok" } else { "err" },
val = val
.map(|val| format!("`{val}`"))
.unwrap_or_else(|| "empty response".to_string())
)),
)),
version,
)),
}
}