aboutsummaryrefslogtreecommitdiff
path: root/dev_tools
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-04-11 22:28:26 +0800
committer魏曹先生 <1992414357@qq.com>2026-04-11 22:28:26 +0800
commitdc501290f7b25b72edf8c67555b5604ac5fc8a59 (patch)
treeb6c4064e46ddef919a561a846c9770f432f821d2 /dev_tools
parentd6f0e3f8f97a27a464d9610500c29fb817a2ef88 (diff)
Add dev tools to generate example documentation
Diffstat (limited to 'dev_tools')
-rw-r--r--dev_tools/Cargo.lock26
-rw-r--r--dev_tools/Cargo.toml8
-rw-r--r--dev_tools/src/bin/refresh-examples.rs139
-rw-r--r--dev_tools/src/lib.rs1
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 @@
+