use std::collections::HashMap;
use axum::{Json, response::IntoResponse};
use http::StatusCode;
use log::{debug, error, info};
use run_code_rmcp::{CodeExecutor, LanguageScript, RunCodeHttpResult};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::AppError;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RunCodeMessageRequest {
pub json_param: HashMap<String, Value>,
pub code: String,
pub uid: String,
pub engine_type: String,
}
impl RunCodeMessageRequest {
pub fn get_language_script(&self) -> LanguageScript {
match self.engine_type.as_str() {
"js" => LanguageScript::Js,
"ts" => LanguageScript::Ts,
"python" => LanguageScript::Python,
_ => LanguageScript::Js,
}
}
}
pub async fn run_code_handler(
Json(run_code_message_request): Json<RunCodeMessageRequest>,
) -> Result<impl IntoResponse, AppError> {
let params = match serde_json::to_value(run_code_message_request.json_param.clone()) {
Ok(v) => v,
Err(e) => {
error!("Run_code_handler parameter serialization failed: {e:?}");
return Err(AppError::from(e));
}
};
let code = run_code_message_request.code.clone();
let language = run_code_message_request.get_language_script();
debug!("run_code_handler language:{language:?}");
debug!("run_code_handler code:{code:?}");
debug!("run_code_handler params:{params:?}");
let result = match CodeExecutor::execute_with_params(&code, language, Some(params), None).await
{
Ok(result) => result,
Err(e) => {
error!("run_code_handler execution failed: {e:?}");
return Err(AppError::from(e));
}
};
if !result.success {
let error_message = result
.error
.as_deref()
.unwrap_or("run_code_handler执行失败但未提供错误信息");
error!("run_code_handler execution returns failure: {error_message}");
}
let data = match serde_json::to_value(&result) {
Ok(data) => data,
Err(e) => {
error!("run_code_handler serialization result failed: {e:?}");
return Err(AppError::from(e));
}
};
info!("run_code_handler result:{:?}", &result.success);
debug!("run_code_handler result:{:?}", &data);
let run_code_http_result = RunCodeHttpResult {
data,
success: result.success,
error: result.error.clone(),
};
let body = serde_json::to_string(&run_code_http_result)?;
Ok((StatusCode::OK, body).into_response())
}