///|
/// Return the result message used by human-facing reports.
fn report_message(result : SarifResult) -> String {
  match result.message.text {
    Some(text) => text
    None =>
      match result.message.markdown {
        Some(markdown) => markdown
        None => ""
      }
  }
}

///|
fn report_level(result : SarifResult) -> String {
  match result.level {
    Some(level) => level
    None => "none"
  }
}

///|
fn report_baseline_state(result : SarifResult) -> String {
  match result.baselineState {
    Some(state) => state
    None => "-"
  }
}

///|
fn format_location(location : Location) -> String? {
  match location.physicalLocation {
    Some(physical) => {
      let path = match physical.artifactLocation {
        Some(artifact) =>
          match artifact.uri {
            Some(uri) => normalize_path(uri)
            None => ""
          }
        None => ""
      }
      if path.is_empty() {
        None
      } else {
        let line = match physical.region {
          Some(region) =>
            match region.startLine {
              Some(value) => value.to_string()
              None => ""
            }
          None => ""
        }
        let column = match physical.region {
          Some(region) =>
            match region.startColumn {
              Some(value) => value.to_string()
              None => ""
            }
          None => ""
        }
        let line_suffix = match line.is_empty() {
          true => ""
          false => ":" + line
        }
        let column_suffix = match column.is_empty() {
          true => ""
          false => ":" + column
        }
        Some(path + line_suffix + column_suffix)
      }
    }
    None => None
  }
}

///|
fn report_location(result : SarifResult) -> String {
  match result.locations {
    Some(locations) => {
      for location in locations {
        match format_location(location) {
          Some(value) => return value
          None => ()
        }
      }
      "-"
    }
    None => "-"
  }
}

///|
fn markdown_cell(value : String) -> String {
  value.replace(old="|", new="\\|").replace(old="\n", new="
") } ///| fn html_escape(value : String) -> String { value .replace(old="&", new="&") .replace(old="<", new="<") .replace(old=">", new=">") .replace(old="\"", new=""") .replace(old="'", new="'") .replace(old="\n", new="
") } ///| /// Render a compact Markdown report for a SARIF log. pub fn render_markdown(log : SarifLog) -> String { let summary = summarize(log) let output = "# MoonSARIF Report\n\n" + "## Summary\n\n" + "| Metric | Value |\n| --- | ---: |\n" + "| Runs | " + summary.run_count.to_string() + " |\n" + "| Results | " + summary.result_count.to_string() + " |\n" + "| Errors | " + summary.error_count.to_string() + " |\n" + "| Warnings | " + summary.warning_count.to_string() + " |\n" + "| Notes | " + summary.note_count.to_string() + " |\n" + "| None | " + summary.none_count.to_string() + " |\n" + "| Rules | " + summary.unique_rule_count.to_string() + " |\n\n" + "## Findings\n\n" + "| # | Level | Rule | Location | Message | Baseline |\n" + "| ---: | --- | --- | --- | --- | --- |\n" let mut body = "" let mut index = 1 for run in log.runs { match run.results { Some(results) => for result in results { let rule = match result.ruleId { Some(value) => value None => "-" } body += "| " + index.to_string() + " | " + markdown_cell(report_level(result)) + " | " + markdown_cell(rule) + " | " + markdown_cell(report_location(result)) + " | " + markdown_cell(report_message(result)) + " | " + markdown_cell(report_baseline_state(result)) + " |\n" index += 1 } None => () } } output + body } ///| /// Render a self-contained HTML report for a SARIF log. pub fn render_html(log : SarifLog) -> String { let summary = summarize(log) let mut rows = "" let mut index = 1 for run in log.runs { match run.results { Some(results) => for result in results { let rule = match result.ruleId { Some(value) => value None => "-" } let level = report_level(result) rows += "" + index.to_string() + "" + html_escape(level) + "" + html_escape(rule) + "" + html_escape(report_location(result)) + "" + html_escape(report_message(result)) + "" + html_escape(report_baseline_state(result)) + "\n" index += 1 } None => () } } "\n" + "" + "MoonSARIF Report

MoonSARIF Report

" + "
" + summary.run_count.to_string() + "Runs
" + summary.result_count.to_string() + "Results
" + summary.error_count.to_string() + "Errors
" + summary.warning_count.to_string() + "Warnings
" + summary.note_count.to_string() + "Notes
" + summary.unique_rule_count.to_string() + "Rules

Findings

" + "" + rows + "
#LevelRuleLocationMessageBaseline
" }