aboutsummaryrefslogtreecommitdiff
path: root/dev_tools/src
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-06-05 21:08:07 +0800
committer魏曹先生 <1992414357@qq.com>2026-06-05 21:08:07 +0800
commitd3b4027f5926569cb9371b2ea62b6be9387ea650 (patch)
treed6c9de16cea03253273ad7c89eadc401e5e105b2 /dev_tools/src
parent97853f47489ab58b63e08854f579ae776e5a2d1f (diff)
Add example pages and sync-examples tool for docs
Diffstat (limited to 'dev_tools/src')
-rw-r--r--dev_tools/src/bin/ci.rs1
-rw-r--r--dev_tools/src/bin/sync-examples.rs134
2 files changed, 135 insertions, 0 deletions
diff --git a/dev_tools/src/bin/ci.rs b/dev_tools/src/bin/ci.rs
index 86b930c..a90c413 100644
--- a/dev_tools/src/bin/ci.rs
+++ b/dev_tools/src/bin/ci.rs
@@ -123,6 +123,7 @@ fn docs_refresh() -> Result<(), i32> {
run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin docsify-sidebar-gen")?;
run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin refresh-docs")?;
run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin refresh-feature-mod")?;
+ run_cmd!("cargo run --manifest-path dev_tools/Cargo.toml --bin sync-examples")?;
Ok(())
}
diff --git a/dev_tools/src/bin/sync-examples.rs b/dev_tools/src/bin/sync-examples.rs
new file mode 100644
index 0000000..c317af6
--- /dev/null
+++ b/dev_tools/src/bin/sync-examples.rs
@@ -0,0 +1,134 @@
+use std::fs;
+use std::path::Path;
+
+use serde::{Deserialize, Serialize};
+use tools::println_cargo_style;
+
+#[derive(Serialize)]
+struct ExampleMeta {
+ id: String,
+ name: String,
+ icon: String,
+ category: String,
+ desc: String,
+ tags: Vec<String>,
+ files: Vec<String>,
+}
+
+#[derive(Deserialize)]
+struct PageToml {
+ example: PageTomlExample,
+}
+
+#[derive(Deserialize)]
+struct PageTomlExample {
+ id: String,
+ #[serde(default)]
+ name: String,
+ #[serde(default = "default_icon")]
+ icon: String,
+ #[serde(default)]
+ category: String,
+ #[serde(default)]
+ desc: String,
+ #[serde(default)]
+ tags: Vec<String>,
+ #[serde(default = "default_files")]
+ files: Vec<String>,
+}
+
+fn default_icon() -> String {
+ "📦".to_string()
+}
+
+fn default_files() -> Vec<String> {
+ vec!["Cargo.toml".to_string(), "src/main.rs".to_string()]
+}
+
+fn main() {
+ #[cfg(windows)]
+ let _ = colored::control::set_virtual_terminal(true);
+
+ let examples_dir = Path::new("examples");
+ let output_dir = Path::new("docs/example-pages");
+ fs::create_dir_all(output_dir).expect("failed to create docs/example-pages");
+
+ let mut examples: Vec<ExampleMeta> = Vec::new();
+
+ let entries = fs::read_dir(examples_dir).expect("failed to read examples/");
+ for entry in entries.flatten() {
+ let path = entry.path();
+ if !path.is_dir() {
+ continue;
+ }
+
+ let dir_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
+ if !dir_name.starts_with("example-") {
+ continue;
+ }
+
+ let id = dir_name.to_string();
+ let page_toml_path = path.join("page.toml");
+
+ let meta = if page_toml_path.exists() {
+ match fs::read_to_string(&page_toml_path)
+ .map_err(|e| e.to_string())
+ .and_then(|content| toml::from_str::<PageToml>(&content).map_err(|e| e.to_string()))
+ {
+ Ok(page) => {
+ let ex = page.example;
+ ExampleMeta {
+ id: if ex.id.is_empty() { id.clone() } else { ex.id },
+ name: if ex.name.is_empty() {
+ id.clone()
+ } else {
+ ex.name
+ },
+ icon: ex.icon,
+ category: ex.category,
+ desc: ex.desc,
+ tags: ex.tags,
+ files: if ex.files.is_empty() {
+ default_files()
+ } else {
+ ex.files
+ },
+ }
+ }
+ Err(e) => {
+ eprintln!(
+ "Warning: failed to parse {}: {}",
+ page_toml_path.display(),
+ e
+ );
+ continue;
+ }
+ }
+ } else {
+ continue;
+ };
+
+ examples.push(meta);
+ }
+
+ // Sort: basic first, then alphabetical
+ examples.sort_by(|a, b| {
+ if a.id == "example-basic" {
+ return std::cmp::Ordering::Less;
+ }
+ if b.id == "example-basic" {
+ return std::cmp::Ordering::Greater;
+ }
+ a.id.cmp(&b.id)
+ });
+
+ let json = serde_json::to_string_pretty(&examples).expect("failed to serialize");
+ let output_path = output_dir.join("examples.json");
+ fs::write(&output_path, &json).expect("failed to write examples.json");
+
+ println_cargo_style!(
+ "Sync: {} examples -> {}",
+ examples.len(),
+ output_path.display()
+ );
+}