diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-11 22:28:26 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-11 22:28:26 +0800 |
| commit | dc501290f7b25b72edf8c67555b5604ac5fc8a59 (patch) | |
| tree | b6c4064e46ddef919a561a846c9770f432f821d2 /dev_tools | |
| parent | d6f0e3f8f97a27a464d9610500c29fb817a2ef88 (diff) | |
Add dev tools to generate example documentation
Diffstat (limited to 'dev_tools')
| -rw-r--r-- | dev_tools/Cargo.lock | 26 | ||||
| -rw-r--r-- | dev_tools/Cargo.toml | 8 | ||||
| -rw-r--r-- | dev_tools/src/bin/refresh-examples.rs | 139 | ||||
| -rw-r--r-- | dev_tools/src/lib.rs | 1 |
4 files changed, 174 insertions, 0 deletions
diff --git a/dev_tools/Cargo.lock b/dev_tools/Cargo.lock new file mode 100644 index 0000000..39a1521 --- /dev/null +++ b/dev_tools/Cargo.lock @@ -0,0 +1,26 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "just_fmt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5454cda0d57db59778608d7a47bff5b16c6705598265869fb052b657f66cf05e" + +[[package]] +name = "just_template" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3edb658c34b10b69c4b3b58f7ba989cd09c82c0621dee1eef51843c2327225" +dependencies = [ + "just_fmt", +] + +[[package]] +name = "tools" +version = "0.1.0" +dependencies = [ + "just_fmt", + "just_template", +] diff --git a/dev_tools/Cargo.toml b/dev_tools/Cargo.toml new file mode 100644 index 0000000..a28b156 --- /dev/null +++ b/dev_tools/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "tools" +version = "0.1.0" +edition = "2024" + +[dependencies] +just_template = "0.1.3" +just_fmt = "0.1.2" diff --git a/dev_tools/src/bin/refresh-examples.rs b/dev_tools/src/bin/refresh-examples.rs new file mode 100644 index 0000000..9fdc7b5 --- /dev/null +++ b/dev_tools/src/bin/refresh-examples.rs @@ -0,0 +1,139 @@ +use std::path::PathBuf; + +use just_fmt::snake_case; +use just_template::{Template, tmpl}; + +const EXAMPLE_ROOT: &str = "./examples/"; +const OUTPUT_PATH: &str = "./mingling/src/example_docs.rs"; + +const TEMPLATE_CONTENT: &str = include_str!("../../../mingling/src/example_docs.rs.tmpl"); + +struct ExampleContent { + name: String, + header: String, + code: String, + cargo_toml: String, +} + +impl ExampleContent { + pub fn read(name: &str) -> Self { + let repo = find_git_repo().unwrap(); + let cargo_toml = Self::read_cargo_toml(&repo, name); + let (header, code) = Self::read_header_and_code(&repo, name); + + let cargo_toml = cargo_toml + .lines() + .map(|line| format!("/// {}", line)) + .collect::<Vec<_>>() + .join("\n"); + + let header = header + .lines() + .map(|line| format!("/// {}", line)) + .collect::<Vec<_>>() + .join("\n"); + + let code = code + .lines() + .map(|line| format!("/// {}", line)) + .collect::<Vec<_>>() + .join("\n"); + + ExampleContent { + name: name.to_string(), + header, + code, + cargo_toml, + } + } + + fn read_header_and_code(repo: &PathBuf, name: &str) -> (String, String) { + let file_path = repo + .join(EXAMPLE_ROOT) + .join(name) + .join("src") + .join("main.rs"); + let content = std::fs::read_to_string(&file_path).unwrap_or_default(); + let mut lines = content.lines(); + let mut header = String::new(); + let mut code = String::new(); + + // Collect header lines (starting with //!) + while let Some(line) = lines.next() { + if line.trim_start().starts_with("//!") { + let trimmed = line.trim_start_matches("//!").trim(); + header.push_str(trimmed); + header.push('\n'); + } else { + // First non-header line found, start collecting code + code.push_str(line); + code.push('\n'); + break; + } + } + + // Collect remaining code lines + for line in lines { + code.push_str(line); + code.push('\n'); + } + + (header.trim().to_string(), code.trim().to_string()) + } + + fn read_cargo_toml(repo: &PathBuf, name: &str) -> String { + let file_path = repo.join(EXAMPLE_ROOT).join(name).join("Cargo.toml"); + let content = std::fs::read_to_string(&file_path).unwrap_or_default(); + content + } +} + +fn main() { + let mut template = Template::from(TEMPLATE_CONTENT); + let repo_root = find_git_repo().unwrap(); + let example_root = repo_root.join(EXAMPLE_ROOT); + let mut examples = Vec::new(); + if let Ok(entries) = std::fs::read_dir(&example_root) { + for entry in entries.flatten() { + if let Ok(file_type) = entry.file_type() { + if file_type.is_dir() { + let example_name = entry.file_name().to_string_lossy().to_string(); + let example_content = ExampleContent::read(&example_name); + examples.push(example_content); + } + } + } + } + + for example in examples { + tmpl!(template += { + examples { + ( + example_header = example.header, + example_import = example.cargo_toml, + example_code = example.code, + example_name = snake_case!(example.name) + ) + } + }); + } + + std::fs::write(repo_root.join(OUTPUT_PATH), template.to_string()).unwrap(); +} + +fn find_git_repo() -> Option<std::path::PathBuf> { + let mut current_dir = std::env::current_dir().ok()?; + + loop { + let git_dir = current_dir.join(".git"); + if git_dir.exists() && git_dir.is_dir() { + return Some(current_dir); + } + + if !current_dir.pop() { + break; + } + } + + None +} diff --git a/dev_tools/src/lib.rs b/dev_tools/src/lib.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/dev_tools/src/lib.rs @@ -0,0 +1 @@ + |
