Path: blob/main/tools/build-templated-pages/src/examples.rs
6595 views
use core::cmp::Ordering;1use std::fs::File;23use hashbrown::HashMap;4use serde::Serialize;5use tera::{Context, Tera};6use toml_edit::{DocumentMut, Item};78use crate::Command;910#[derive(Debug, Serialize, PartialEq, Eq)]11struct Category {12description: Option<String>,13examples: Vec<Example>,14}1516#[derive(Debug, Serialize, PartialEq, Eq)]17struct Example {18technical_name: String,19path: String,20name: String,21description: String,22category: String,23wasm: bool,24}2526impl Ord for Example {27fn cmp(&self, other: &Self) -> Ordering {28(&self.category, &self.name).cmp(&(&other.category, &other.name))29}30}3132impl PartialOrd for Example {33fn partial_cmp(&self, other: &Self) -> Option<Ordering> {34Some(self.cmp(other))35}36}3738fn parse_examples(panic_on_missing: bool) -> Vec<Example> {39let manifest_file = std::fs::read_to_string("Cargo.toml").unwrap();40let manifest = manifest_file.parse::<DocumentMut>().unwrap();41let metadatas = manifest42.get("package")43.unwrap()44.get("metadata")45.as_ref()46.unwrap()["example"]47.clone();4849manifest["example"]50.as_array_of_tables()51.unwrap()52.iter()53.flat_map(|val| {54let technical_name = val.get("name").unwrap().as_str().unwrap().to_string();55if panic_on_missing && metadatas.get(&technical_name).is_none() {56panic!("Missing metadata for example {technical_name}");57}58if panic_on_missing && val.get("doc-scrape-examples").is_none() {59panic!("Example {technical_name} is missing doc-scrape-examples");60}6162if metadatas63.get(&technical_name)64.and_then(|metadata| metadata.get("hidden"))65.and_then(Item::as_bool)66.unwrap_or(false)67{68return None;69}7071metadatas.get(&technical_name).map(|metadata| Example {72technical_name,73path: val["path"].as_str().unwrap().to_string(),74name: metadata["name"].as_str().unwrap().to_string(),75description: metadata["description"].as_str().unwrap().to_string(),76category: metadata["category"].as_str().unwrap().to_string(),77wasm: metadata["wasm"].as_bool().unwrap(),78})79})80.collect()81}8283fn parse_categories() -> HashMap<Box<str>, String> {84let manifest_file = std::fs::read_to_string("Cargo.toml").unwrap();85let manifest = manifest_file.parse::<DocumentMut>().unwrap();86manifest87.get("package")88.unwrap()89.get("metadata")90.as_ref()91.unwrap()["example_category"]92.clone()93.as_array_of_tables()94.unwrap()95.iter()96.map(|v| {97(98v.get("name").unwrap().as_str().unwrap().into(),99v.get("description").unwrap().as_str().unwrap().to_string(),100)101})102.collect()103}104105pub(crate) fn check(what_to_run: Command) {106let examples = parse_examples(what_to_run.contains(Command::CHECK_MISSING));107108if what_to_run.contains(Command::UPDATE) {109let categories = parse_categories();110let examples_by_category: HashMap<Box<str>, Category> = examples111.into_iter()112.fold(HashMap::<Box<str>, Vec<Example>>::new(), |mut v, ex| {113v.entry_ref(ex.category.as_str()).or_default().push(ex);114v115})116.into_iter()117.map(|(key, mut examples)| {118examples.sort();119let description = categories.get(&key).cloned();120(121key,122Category {123description,124examples,125},126)127})128.collect();129130let mut context = Context::new();131context.insert("all_examples", &examples_by_category);132Tera::new("docs-template/*.md.tpl")133.expect("error parsing template")134.render_to(135"EXAMPLE_README.md.tpl",136&context,137File::create("examples/README.md").expect("error creating file"),138)139.expect("error rendering template");140}141}142143144