From a00ca6ae970df5ec5e5872300b75c340f9699542 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:24:29 +0100 Subject: [PATCH] stuff --- src/main.rs | 82 ++++++++++++++++++++++++++++------------------- src/parse.rs | 9 +----- src/render.rs | 88 ++++++++++++++++++++++----------------------------- 3 files changed, 87 insertions(+), 92 deletions(-) diff --git a/src/main.rs b/src/main.rs index e03d039..f80467e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,12 +2,13 @@ mod parse; mod render; use std::{ + collections::HashMap, path::{Path, PathBuf}, process::Command, }; use eyre::{bail, Context, OptionExt, Result}; -use parse::{Footnote, ParsedTargetInfoFile, Tier, TriStateBool}; +use parse::ParsedTargetInfoFile; use serde::Deserialize; /// Information about a target obtained from the target_info markdown file. @@ -52,14 +53,24 @@ fn main() -> Result<()> { .wrap_err("failed loading target_info")? .into_iter() .map(|info| { - let metadata_used = vec![false; info.metadata.len()]; - TargetPatternEntry { info, used: false, footnotes_used: metadata_used } + let footnotes_used = info + .footnotes + .iter() + .map(|(target, _)| (target.clone(), false)) + .collect(); + TargetPatternEntry { + info, + used: false, + footnotes_used, + } }) .collect::>(); eprintln!("Collecting rustc information"); - let rustc_infos = - targets.iter().map(|target| rustc_target_info(&rustc, target)).collect::>(); + let rustc_infos = targets + .iter() + .map(|target| rustc_target_info(&rustc, target)) + .collect::>(); let targets = targets .into_iter() @@ -68,7 +79,9 @@ fn main() -> Result<()> { .collect::>(); eprintln!("Rendering targets check_only={check_only}"); - let targets_dir = Path::new(output_src).join("platform-support").join("targets"); + let targets_dir = Path::new(output_src) + .join("platform-support") + .join("targets"); if !check_only { std::fs::create_dir_all(&targets_dir).wrap_err("creating platform-support/targets dir")?; } @@ -83,17 +96,19 @@ fn main() -> Result<()> { for target_pattern in info_patterns { if !target_pattern.used { - bail!("target pattern `{}` was never used", target_pattern.info.pattern); + bail!( + "target pattern `{}` was never used", + target_pattern.info.pattern + ); } - for (used, meta) in - std::iter::zip(target_pattern.footnotes_used, target_pattern.info.metadata) - { + for footnote_target in target_pattern.info.footnotes.keys() { + let used = target_pattern.footnotes_used[footnote_target]; if !used { bail!( "in target pattern `{}`, the footnotes for target `{}` were never used", target_pattern.info.pattern, - meta.target + footnote_target, ); } } @@ -108,7 +123,7 @@ fn main() -> Result<()> { struct TargetPatternEntry { info: ParsedTargetInfoFile, used: bool, - footnotes_used: Vec, + footnotes_used: HashMap, } fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> TargetDocs { @@ -116,7 +131,6 @@ fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> Ta let mut maintainers = Vec::new(); let mut sections = Vec::new(); - let mut metadata = None; let mut footnotes = Vec::new(); for target_pattern_entry in info_patterns { @@ -145,32 +159,24 @@ fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> Ta } if let Some(target_footnotes) = target_pattern.footnotes.get(target) { - target_pattern_entry.footnotes_used[i] = true; + target_pattern_entry + .footnotes_used + .insert(target.to_owned(), true); if !footnotes.is_empty() { panic!("target {target} is assigned metadata from more than one pattern"); } footnotes = target_footnotes.clone(); } - - for (i, metadata_pattern) in target_pattern.metadata.iter().enumerate() { - if metadata_pattern.target == target { - target_pattern_entry.footnotes_used[i] = true; - if metadata.is_some() { - panic!("target {target} is assigned metadata from more than one pattern"); - } - metadata = Some(TargetMetadata { - notes: metadata_pattern.notes.clone(), - host: metadata_pattern.host.clone(), - std: metadata_pattern.std.clone(), - footnotes: metadata_pattern.footnotes.clone(), - }); - } - } } } - TargetDocs { name: target.to_owned(), maintainers, sections, footnotes } + TargetDocs { + name: target.to_owned(), + maintainers, + sections, + footnotes, + } } /// Information about a target obtained from rustc. @@ -212,11 +218,21 @@ fn rustc_target_info(rustc: &Path, target: &str) -> RustcTargetInfo { let json_spec = rustc_stdout( rustc, - &["-Zunstable-options", "--print", "target-spec-json", "--target", target], + &[ + "-Zunstable-options", + "--print", + "target-spec-json", + "--target", + target, + ], ); - let spec = serde_json::from_str::(&json_spec); + let spec = serde_json::from_str::(&json_spec) + .expect("parsing --print target-spec-json for metadata"); - RustcTargetInfo { target_cfgs, metadata: spec.metadata } + RustcTargetInfo { + target_cfgs, + metadata: spec.metadata, + } } fn rustc_stdout(rustc: &Path, args: &[&str]) -> String { diff --git a/src/parse.rs b/src/parse.rs index 00fc64a..c09e7ea 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -86,16 +86,9 @@ fn parse_file(name: &str, content: &str) -> Result { let frontmatter_line_count = frontmatter.lines().count() + 2; // 2 from --- - let mut frontmatter = + let frontmatter = serde_yaml::from_str::(frontmatter).wrap_err("invalid frontmatter")?; - frontmatter.metadata.iter_mut().for_each(|meta| { - meta.footnotes.iter_mut().for_each(|footnote| { - footnote.content = footnote.content.replace("\r\n", " ").replace("\n", " ") - }) - }); - let frontmatter = frontmatter; - let body = frontmatter_splitter.next().ok_or_eyre("no body")?; let mut sections = Vec::<(String, String)>::new(); diff --git a/src/render.rs b/src/render.rs index c90a0f5..96107ca 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,27 +1,18 @@ use eyre::{Context, OptionExt, Result}; use std::{fs, path::Path}; -use crate::{ - parse::{Footnote, Tier, TriStateBool}, - RustcTargetInfo, TargetDocs, -}; - -impl TargetDocs { - fn has_host_tools(&self) -> bool { - self.metadata.as_ref().map_or(false, |meta| meta.host == TriStateBool::True) - } -} +use crate::{RustcTargetInfo, TargetDocs}; /// Renders a single target markdown file from the information obtained. pub fn render_target_md(target: &TargetDocs, rustc_info: &RustcTargetInfo) -> String { let mut doc = format!( "# {}\n\n**Tier: {}**\n\n", target.name, - match target.tier { - Some(Tier::One) => "1", - Some(Tier::Two) => "2", - Some(Tier::Three) => "3", - None => "UNKNOWN", + match rustc_info.metadata.tier { + Some(1) => "1", + Some(2) => "2", + Some(3) => "3", + _ => "UNKNOWN", } ); @@ -61,7 +52,10 @@ pub fn render_target_md(target: &TargetDocs, rustc_info: &RustcTargetInfo) -> St section("Maintainers", &maintainers_content); for section_name in crate::SECTIONS { - let value = target.sections.iter().find(|(name, _)| name == section_name); + let value = target + .sections + .iter() + .find(|(name, _)| name == section_name); let section_content = match value { Some((_, value)) => value.clone(), @@ -141,12 +135,6 @@ pub fn render_static( Ok(()) } -impl Footnote { - fn reference(&self) -> String { - format!("[^{}]", self.name) - } -} - fn render_platform_support_tables( content: &str, targets: &[(TargetDocs, RustcTargetInfo)], @@ -160,7 +148,7 @@ fn render_platform_support_tables( content, "TIER1HOST", TierTable { - filter: |target| target.tier == Some(Tier::One), + filter: |target| target.1.metadata.tier == Some(1), include_host: false, include_std: false, }, @@ -169,7 +157,9 @@ fn render_platform_support_tables( &content, "TIER2HOST", TierTable { - filter: |target| target.tier == Some(Tier::Two) && target.has_host_tools(), + filter: |target| { + target.1.metadata.tier == Some(2) && target.1.metadata.host_tools.unwrap_or(false) + }, include_host: false, include_std: false, }, @@ -178,7 +168,9 @@ fn render_platform_support_tables( &content, "TIER2", TierTable { - filter: |target| target.tier == Some(Tier::Two) && !target.has_host_tools(), + filter: |target| { + target.1.metadata.tier == Some(2) && !target.1.metadata.host_tools.unwrap_or(false) + }, include_host: false, include_std: true, }, @@ -187,7 +179,7 @@ fn render_platform_support_tables( &content, "TIER3", TierTable { - filter: |target| target.tier == Some(Tier::Three), + filter: |target| target.1.metadata.tier == Some(3), include_host: true, include_std: true, }, @@ -196,49 +188,50 @@ fn render_platform_support_tables( Ok(content) } -fn render_table_tri_state_bool(bool: TriStateBool) -> &'static str { +fn render_table_option_bool(bool: Option) -> &'static str { match bool { - TriStateBool::True => "✓", - TriStateBool::False => " ", - TriStateBool::Unknown => "?", + Some(true) => "✓", + Some(false) => " ", + None => "?", } } struct TierTable { - filter: fn(&TargetDocs) -> bool, + filter: fn(&(TargetDocs, RustcTargetInfo)) -> bool, include_std: bool, include_host: bool, } fn render_table(targets: &[(TargetDocs, RustcTargetInfo)], table: TierTable) -> Result { let mut rows = Vec::new(); - let mut all_footnotes = Vec::new(); - let targets = targets.into_iter().filter(|target| (table.filter)(&target.0)); + let targets = targets.into_iter().filter(|target| (table.filter)(&target)); - for (target, _) in targets { - let meta = target.metadata.as_ref(); + for (target, rustc_info) in targets { + let meta = &rustc_info.metadata; - let mut notes = meta.map(|meta| meta.notes.as_str()).unwrap_or("unknown").to_owned(); + let mut notes = meta.description.as_deref().unwrap_or("unknown").to_owned(); - if meta.map_or(false, |meta| !meta.footnotes.is_empty()) { - let footnotes = &meta.unwrap().footnotes; - all_footnotes.extend(footnotes); - let footnotes_str = - footnotes.iter().map(|footnote| footnote.reference()).collect::>().join(" "); + if !target.footnotes.is_empty() { + let footnotes_str = target + .footnotes + .iter() + .map(|footnote| format!("[^{}]", footnote)) + .collect::>() + .join(" "); notes = format!("{notes} {footnotes_str}"); } let std = if table.include_std { - let std = meta.map(|meta| render_table_tri_state_bool(meta.std)).unwrap_or("?"); + let std = render_table_option_bool(meta.std); format!(" | {std}") } else { String::new() }; let host = if table.include_host { - let host = meta.map(|meta| render_table_tri_state_bool(meta.host)).unwrap_or("?"); + let host = render_table_option_bool(meta.host_tools); format!(" | {host}") } else { String::new() @@ -250,14 +243,7 @@ fn render_table(targets: &[(TargetDocs, RustcTargetInfo)], table: TierTable) -> )); } - let mut result = rows.join("\n"); - - for footnote in all_footnotes { - result.push_str("\n\n"); - result.push_str(&footnote.reference()); - result.push_str(": "); - result.push_str(&footnote.content); - } + let result = rows.join("\n"); Ok(result) }