#![cfg_attr(coverage_nightly, coverage(off))]
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MetaFileType {
Makefile,
Readme,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetaFile {
pub path: PathBuf,
pub file_type: MetaFileType,
pub content: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CompressedMakefile {
pub variables: Vec<String>,
pub targets: Vec<MakeTarget>,
pub detected_toolchain: Option<String>,
pub key_dependencies: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MakeTarget {
pub name: String,
pub deps: Vec<String>,
pub recipe_summary: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CompressedReadme {
pub sections: Vec<CompressedSection>,
pub project_description: Option<String>,
pub key_features: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompressedSection {
pub title: String,
pub content: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BuildInfo {
pub toolchain: String,
pub targets: Vec<String>,
pub dependencies: Vec<String>,
pub primary_command: Option<String>,
}
impl BuildInfo {
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn from_makefile(compressed: CompressedMakefile) -> Self {
Self {
toolchain: compressed
.detected_toolchain
.unwrap_or_else(|| "unknown".to_string()),
targets: compressed.targets.iter().map(|t| t.name.clone()).collect(),
dependencies: compressed.key_dependencies,
primary_command: compressed
.targets
.iter()
.find(|t| t.name == "all" || t.name == "build")
.map(|t| t.recipe_summary.clone()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProjectOverview {
pub compressed_description: String,
pub key_features: Vec<String>,
pub architecture_summary: Option<String>,
pub api_summary: Option<String>,
}
impl CompressedReadme {
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn to_summary(&self) -> ProjectOverview {
let mut overview = ProjectOverview {
compressed_description: self.project_description.clone().unwrap_or_default(),
key_features: self.key_features.clone(),
architecture_summary: None,
api_summary: None,
};
for section in &self.sections {
let title_lower = section.title.to_lowercase();
if title_lower.contains("architecture") && overview.architecture_summary.is_none() {
overview.architecture_summary = Some(section.content.clone());
} else if (title_lower.contains("api") || title_lower.contains("interface"))
&& overview.api_summary.is_none()
{
overview.api_summary = Some(section.content.clone());
}
}
overview
}
}
include!("project_meta_tests.rs");
include!("project_meta_proptests.rs");