aboutsummaryrefslogtreecommitdiff
path: root/dev_tools
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
parent97853f47489ab58b63e08854f579ae776e5a2d1f (diff)
Add example pages and sync-examples tool for docs
Diffstat (limited to 'dev_tools')
-rw-r--r--dev_tools/Cargo.lock26
-rw-r--r--dev_tools/Cargo.toml1
-rw-r--r--dev_tools/scripts/http-page-preview.ps11
-rwxr-xr-xdev_tools/scripts/http-page-preview.sh1
-rw-r--r--dev_tools/src/bin/ci.rs1
-rw-r--r--dev_tools/src/bin/sync-examples.rs134
6 files changed, 162 insertions, 2 deletions
diff --git a/dev_tools/Cargo.lock b/dev_tools/Cargo.lock
index 35d3a8f..1180474 100644
--- a/dev_tools/Cargo.lock
+++ b/dev_tools/Cargo.lock
@@ -34,6 +34,12 @@ dependencies = [
]
[[package]]
+name = "itoa"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+
+[[package]]
name = "just_fmt"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -103,6 +109,19 @@ dependencies = [
]
[[package]]
+name = "serde_json"
+version = "1.0.150"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+dependencies = [
+ "itoa",
+ "memchr",
+ "serde",
+ "serde_core",
+ "zmij",
+]
+
+[[package]]
name = "serde_spanned"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -171,6 +190,7 @@ dependencies = [
"just_fmt",
"just_template",
"serde",
+ "serde_json",
"toml",
]
@@ -203,3 +223,9 @@ checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
dependencies = [
"memchr",
]
+
+[[package]]
+name = "zmij"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/dev_tools/Cargo.toml b/dev_tools/Cargo.toml
index 280a50c..a904bd5 100644
--- a/dev_tools/Cargo.toml
+++ b/dev_tools/Cargo.toml
@@ -16,3 +16,4 @@ just_fmt = "0.1.2"
colored = "3.1.1"
toml = "0.8"
serde = { version = "1", features = ["derive"] }
+serde_json = "1"
diff --git a/dev_tools/scripts/http-page-preview.ps1 b/dev_tools/scripts/http-page-preview.ps1
index 79ed77a..8cc3579 100644
--- a/dev_tools/scripts/http-page-preview.ps1
+++ b/dev_tools/scripts/http-page-preview.ps1
@@ -1,4 +1,3 @@
$starting_dir = Get-Location
-Set-Location "docs"
python -m http.server 3000
Set-Location $starting_dir
diff --git a/dev_tools/scripts/http-page-preview.sh b/dev_tools/scripts/http-page-preview.sh
index 6c822d8..bed4b1c 100755
--- a/dev_tools/scripts/http-page-preview.sh
+++ b/dev_tools/scripts/http-page-preview.sh
@@ -1,3 +1,2 @@
#!/bin/bash
-cd "docs"
python3 -m http.server 3000
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()
+ );
+}