use melodium::LoadingConfig;
use melodium_common::descriptor::{Collection, Identifier, LoadingError, LoadingResult};
use melodium_loader::PackageInfo;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, path::PathBuf, sync::Arc};
#[derive(Debug, Deserialize, JsonSchema)]
pub struct CheckProgramRequest {
pub path: String,
pub entrypoint: Option<String>,
pub force_identifier: Option<String>,
pub all: Option<bool>,
}
#[derive(Debug, Serialize, JsonSchema)]
pub struct Diagnostic {
pub id: u32,
pub message: String,
}
impl From<&LoadingError> for Diagnostic {
fn from(error: &LoadingError) -> Self {
Self {
id: error.id,
message: error.kind.to_string(),
}
}
}
#[derive(Debug, Serialize, JsonSchema)]
pub struct CheckProgramResult {
pub success: bool,
pub errors: Vec<Diagnostic>,
pub entrypoints: Vec<String>,
}
pub fn check_program(request: CheckProgramRequest) -> CheckProgramResult {
let config = LoadingConfig::new();
let file = PathBuf::from(&request.path);
let all = request.all.unwrap_or(false);
let result = if all {
melodium::load_file_all_entrypoints(file, config)
} else if let Some(identifier) = request.force_identifier.as_deref() {
match Identifier::try_from(identifier) {
Ok(identifier) => melodium::load_file_force_entrypoint(file, &identifier, config),
Err(_) => {
return CheckProgramResult {
success: false,
errors: vec![Diagnostic {
id: 0,
message: format!("'{identifier}' is not a valid identifier"),
}],
entrypoints: Vec::new(),
}
}
}
} else {
let entrypoint = request.entrypoint.as_deref().unwrap_or("main");
melodium::load_file(file, entrypoint, config)
};
to_check_result(&result)
}
fn to_check_result(
result: &LoadingResult<(Arc<dyn PackageInfo>, Arc<Collection>)>,
) -> CheckProgramResult {
let entrypoints = result
.success()
.map(|(pkg, _)| pkg.entrypoints().keys().cloned().collect())
.unwrap_or_default();
let errors = result
.failure()
.into_iter()
.map(Diagnostic::from)
.chain(result.errors().iter().map(Diagnostic::from))
.collect();
CheckProgramResult {
success: result.is_success(),
errors,
entrypoints,
}
}