///|
/// An artifact entry in a reproducible processing manifest.
pub struct AnalysisArtifact {
name : String
kind : String
sample_count : Int
checksum : String
description : String
}
///|
/// A reproducible analysis manifest.
pub struct AnalysisManifest {
project : String
version : String
created_at : Double
toolchain : String
artifacts : Array[AnalysisArtifact]
parameters : Array[(String, String)]
}
///|
/// Create an empty analysis manifest.
pub fn AnalysisManifest::new(
project : String,
version : String,
created_at : Double,
toolchain : String,
) -> AnalysisManifest {
{ project, version, created_at, toolchain, artifacts: [], parameters: [] }
}
///|
/// Add a waveform artifact to a manifest.
pub fn AnalysisManifest::add_waveform(
self : AnalysisManifest,
name : String,
trace : Trace,
description : String,
) -> AnalysisManifest {
let artifacts = self.artifacts.copy()
artifacts.push({
name,
kind: "waveform",
sample_count: trace.npts(),
checksum: waveform_checksum(trace.data),
description,
})
{
project: self.project,
version: self.version,
created_at: self.created_at,
toolchain: self.toolchain,
artifacts,
parameters: self.parameters.copy(),
}
}
///|
/// Add a textual parameter to a manifest.
pub fn AnalysisManifest::add_parameter(
self : AnalysisManifest,
name : String,
value : String,
) -> AnalysisManifest {
let parameters = self.parameters.copy()
parameters.push((name, value))
{
project: self.project,
version: self.version,
created_at: self.created_at,
toolchain: self.toolchain,
artifacts: self.artifacts.copy(),
parameters,
}
}
///|
/// Validate that all manifest artifact names are unique and non-empty.
pub fn validate_analysis_manifest(
manifest : AnalysisManifest,
) -> Result[Unit, String] {
for index = 0; index < manifest.artifacts.length(); index = index + 1 {
if manifest.artifacts[index].name == "" {
return Err("manifest artifact name is empty")
}
for other = 0; other < index; other = other + 1 {
if manifest.artifacts[index].name == manifest.artifacts[other].name {
return Err("manifest artifact names must be unique")
}
}
}
Ok(())
}
///|
/// Serialize a manifest in a stable human-readable form.
pub fn analysis_manifest_to_text(manifest : AnalysisManifest) -> String {
let mut output = "project=" +
manifest.project +
"\nversion=" +
manifest.version +
"\ncreated_at=" +
manifest.created_at.to_string() +
"\ntoolchain=" +
manifest.toolchain +
"\n"
output += "[parameters]\n"
for parameter in manifest.parameters {
output += parameter.0 + "=" + parameter.1 + "\n"
}
output += "[artifacts]\n"
for artifact in manifest.artifacts {
output += artifact.name +
"|" +
artifact.kind +
"|" +
artifact.sample_count.to_string() +
"|" +
artifact.checksum +
"|" +
artifact.description +
"\n"
}
output
}
///|
/// Format a manifest headline.
pub fn analysis_manifest_summary(manifest : AnalysisManifest) -> String {
"project=" +
manifest.project +
" version=" +
manifest.version +
" artifacts=" +
manifest.artifacts.length().to_string() +
" parameters=" +
manifest.parameters.length().to_string()
}