use std::path::Path;
pub fn read_manifest(path: &Path) -> Result<Option<act_types::ComponentInfo>, String> {
if !path.exists() {
return Ok(None);
}
let content = std::fs::read_to_string(path)
.map_err(|e| format!("failed to read {}: {e}", path.display()))?;
let info: act_types::ComponentInfo =
toml::from_str(&content).map_err(|e| format!("failed to parse {}: {e}", path.display()))?;
Ok(Some(info))
}
pub struct Overrides {
pub name: Option<String>,
pub version: Option<String>,
pub description: Option<String>,
pub default_language: Option<String>,
}
pub fn build_component_info(
manifest: Option<act_types::ComponentInfo>,
overrides: Overrides,
) -> act_types::ComponentInfo {
let m = manifest.unwrap_or_default();
let s = m.std;
let name = overrides
.name
.or_else(|| non_empty(s.name.clone()))
.unwrap_or_else(|| std::env::var("CARGO_PKG_NAME").unwrap_or_default());
let version = overrides
.version
.or_else(|| non_empty(s.version.clone()))
.unwrap_or_else(|| std::env::var("CARGO_PKG_VERSION").unwrap_or_default());
let description = overrides
.description
.or_else(|| non_empty(s.description.clone()))
.unwrap_or_else(|| std::env::var("CARGO_PKG_DESCRIPTION").unwrap_or_default());
let default_language = overrides
.default_language
.or(s.default_language)
.or_else(|| Some("en".to_string()));
let mut info = act_types::ComponentInfo::new(name, version, description);
info.std.default_language = default_language;
info.std.capabilities = s.capabilities;
info.extra = m.extra;
info
}
fn non_empty(s: String) -> Option<String> {
if s.is_empty() { None } else { Some(s) }
}