ccgx-workflow 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -5
- package/README.zh-CN.md +35 -5
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/shared/{ccgx-workflow.WgUzkiC3.mjs → ccgx-workflow.SJPbUy5_.mjs} +17 -110
- package/package.json +2 -1
- package/templates/commands/agents/phase-runner.md +321 -321
- package/templates/commands/autonomous.md +792 -792
- package/templates/commands/cancel.md +132 -132
- package/templates/commands/debug.md +226 -226
- package/templates/commands/status.md +206 -206
- package/templates/commands/team.md +484 -0
- package/templates/hooks/ccg-session-state.cjs +510 -510
- package/templates/scripts/ccg-phase-runner-launcher.mjs +467 -467
- package/templates/scripts/invoke-model.mjs +64 -0
- package/templates/skills/domains/ai/SKILL.md +35 -35
- package/templates/skills/domains/ai/agent-dev.md +242 -242
- package/templates/skills/domains/ai/llm-security.md +288 -288
- package/templates/skills/domains/ai/rag-system.md +542 -542
- package/templates/skills/domains/architecture/SKILL.md +43 -43
- package/templates/skills/domains/architecture/api-design.md +225 -225
- package/templates/skills/domains/architecture/cloud-native.md +285 -285
- package/templates/skills/domains/architecture/security-arch.md +297 -297
- package/templates/skills/domains/data-engineering/SKILL.md +208 -208
- package/templates/skills/domains/development/SKILL.md +47 -47
- package/templates/skills/domains/development/cpp.md +246 -246
- package/templates/skills/domains/development/go.md +323 -323
- package/templates/skills/domains/development/java.md +277 -277
- package/templates/skills/domains/development/python.md +288 -288
- package/templates/skills/domains/development/rust.md +313 -313
- package/templates/skills/domains/development/shell.md +313 -313
- package/templates/skills/domains/development/typescript.md +277 -277
- package/templates/skills/domains/devops/SKILL.md +40 -40
- package/templates/skills/domains/devops/database.md +217 -217
- package/templates/skills/domains/devops/devsecops.md +198 -198
- package/templates/skills/domains/devops/git-workflow.md +181 -181
- package/templates/skills/domains/devops/testing.md +283 -283
- package/templates/skills/domains/frontend-design/SKILL.md +244 -244
- package/templates/skills/domains/frontend-design/claymorphism/SKILL.md +121 -121
- package/templates/skills/domains/frontend-design/component-patterns.md +202 -202
- package/templates/skills/domains/frontend-design/glassmorphism/SKILL.md +142 -142
- package/templates/skills/domains/frontend-design/liquid-glass/SKILL.md +139 -139
- package/templates/skills/domains/frontend-design/neubrutalism/SKILL.md +145 -145
- package/templates/skills/domains/frontend-design/state-management.md +680 -680
- package/templates/skills/domains/frontend-design/ui-aesthetics.md +110 -110
- package/templates/skills/domains/frontend-design/ux-principles.md +156 -156
- package/templates/skills/domains/infrastructure/SKILL.md +201 -201
- package/templates/skills/domains/mobile/SKILL.md +225 -225
- package/templates/skills/domains/orchestration/SKILL.md +30 -30
- package/templates/skills/domains/orchestration/multi-agent.md +228 -228
- package/templates/skills/domains/security/SKILL.md +73 -73
- package/templates/skills/domains/security/blue-team.md +436 -436
- package/templates/skills/domains/security/code-audit.md +265 -265
- package/templates/skills/domains/security/pentest.md +226 -226
- package/templates/skills/domains/security/red-team.md +374 -374
- package/templates/skills/domains/security/threat-intel.md +372 -372
- package/templates/skills/domains/security/vuln-research.md +369 -369
- package/templates/skills/tools/lib/shared.js +98 -98
- package/templates/skills/tools/override-refusal/SKILL.md +53 -53
- package/templates/skills/tools/override-refusal/scripts/refusal_rewriter.js +226 -226
|
@@ -1,313 +1,313 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: rust
|
|
3
|
-
description: Rust 开发。系统编程、内存安全、高性能、WebAssembly。当用户提到 Rust、Cargo、tokio、内存安全时使用。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 📜 符箓秘典 · Rust
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## 基础语法
|
|
10
|
-
|
|
11
|
-
### 所有权系统
|
|
12
|
-
```rust
|
|
13
|
-
fn main() {
|
|
14
|
-
// 所有权转移
|
|
15
|
-
let s1 = String::from("hello");
|
|
16
|
-
let s2 = s1; // s1 不再有效
|
|
17
|
-
// println!("{}", s1); // 编译错误
|
|
18
|
-
|
|
19
|
-
// 借用
|
|
20
|
-
let s3 = String::from("world");
|
|
21
|
-
let len = calculate_length(&s3); // 借用
|
|
22
|
-
println!("{} has length {}", s3, len); // s3 仍有效
|
|
23
|
-
|
|
24
|
-
// 可变借用
|
|
25
|
-
let mut s4 = String::from("hello");
|
|
26
|
-
change(&mut s4);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
fn calculate_length(s: &String) -> usize {
|
|
30
|
-
s.len()
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
fn change(s: &mut String) {
|
|
34
|
-
s.push_str(", world");
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### 结构体与枚举
|
|
39
|
-
```rust
|
|
40
|
-
// 结构体
|
|
41
|
-
struct User {
|
|
42
|
-
name: String,
|
|
43
|
-
email: String,
|
|
44
|
-
active: bool,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
impl User {
|
|
48
|
-
fn new(name: String, email: String) -> Self {
|
|
49
|
-
Self { name, email, active: true }
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
fn deactivate(&mut self) {
|
|
53
|
-
self.active = false;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// 枚举
|
|
58
|
-
enum Result<T, E> {
|
|
59
|
-
Ok(T),
|
|
60
|
-
Err(E),
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
enum Message {
|
|
64
|
-
Quit,
|
|
65
|
-
Move { x: i32, y: i32 },
|
|
66
|
-
Write(String),
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// 模式匹配
|
|
70
|
-
fn handle_message(msg: Message) {
|
|
71
|
-
match msg {
|
|
72
|
-
Message::Quit => println!("Quit"),
|
|
73
|
-
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
|
|
74
|
-
Message::Write(text) => println!("Write: {}", text),
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### 错误处理
|
|
80
|
-
```rust
|
|
81
|
-
use std::fs::File;
|
|
82
|
-
use std::io::{self, Read};
|
|
83
|
-
|
|
84
|
-
// Result 处理
|
|
85
|
-
fn read_file(path: &str) -> Result<String, io::Error> {
|
|
86
|
-
let mut file = File::open(path)?; // ? 操作符
|
|
87
|
-
let mut contents = String::new();
|
|
88
|
-
file.read_to_string(&mut contents)?;
|
|
89
|
-
Ok(contents)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// 自定义错误
|
|
93
|
-
#[derive(Debug)]
|
|
94
|
-
enum AppError {
|
|
95
|
-
IoError(io::Error),
|
|
96
|
-
ParseError(String),
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
impl From<io::Error> for AppError {
|
|
100
|
-
fn from(err: io::Error) -> Self {
|
|
101
|
-
AppError::IoError(err)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## 异步编程
|
|
107
|
-
|
|
108
|
-
### Tokio
|
|
109
|
-
```rust
|
|
110
|
-
use tokio;
|
|
111
|
-
|
|
112
|
-
#[tokio::main]
|
|
113
|
-
async fn main() {
|
|
114
|
-
let result = fetch_data().await;
|
|
115
|
-
println!("{:?}", result);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async fn fetch_data() -> Result<String, reqwest::Error> {
|
|
119
|
-
let resp = reqwest::get("https://api.example.com/data")
|
|
120
|
-
.await?
|
|
121
|
-
.text()
|
|
122
|
-
.await?;
|
|
123
|
-
Ok(resp)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// 并发执行
|
|
127
|
-
async fn fetch_all(urls: Vec<&str>) -> Vec<String> {
|
|
128
|
-
let futures: Vec<_> = urls.iter()
|
|
129
|
-
.map(|url| fetch_url(url))
|
|
130
|
-
.collect();
|
|
131
|
-
|
|
132
|
-
futures::future::join_all(futures).await
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Channel
|
|
136
|
-
use tokio::sync::mpsc;
|
|
137
|
-
|
|
138
|
-
async fn channel_example() {
|
|
139
|
-
let (tx, mut rx) = mpsc::channel(32);
|
|
140
|
-
|
|
141
|
-
tokio::spawn(async move {
|
|
142
|
-
tx.send("hello").await.unwrap();
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
while let Some(msg) = rx.recv().await {
|
|
146
|
-
println!("Received: {}", msg);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Web 框架
|
|
152
|
-
|
|
153
|
-
### Axum
|
|
154
|
-
```rust
|
|
155
|
-
use axum::{
|
|
156
|
-
routing::{get, post},
|
|
157
|
-
Router, Json, extract::Path,
|
|
158
|
-
};
|
|
159
|
-
use serde::{Deserialize, Serialize};
|
|
160
|
-
|
|
161
|
-
#[derive(Serialize, Deserialize)]
|
|
162
|
-
struct User {
|
|
163
|
-
id: u64,
|
|
164
|
-
name: String,
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async fn get_user(Path(id): Path<u64>) -> Json<User> {
|
|
168
|
-
Json(User { id, name: "Alice".to_string() })
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
async fn create_user(Json(user): Json<User>) -> Json<User> {
|
|
172
|
-
Json(user)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
#[tokio::main]
|
|
176
|
-
async fn main() {
|
|
177
|
-
let app = Router::new()
|
|
178
|
-
.route("/users/:id", get(get_user))
|
|
179
|
-
.route("/users", post(create_user));
|
|
180
|
-
|
|
181
|
-
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
|
182
|
-
.serve(app.into_make_service())
|
|
183
|
-
.await
|
|
184
|
-
.unwrap();
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Actix-web
|
|
189
|
-
```rust
|
|
190
|
-
use actix_web::{web, App, HttpServer, HttpResponse};
|
|
191
|
-
|
|
192
|
-
async fn get_user(path: web::Path<u64>) -> HttpResponse {
|
|
193
|
-
HttpResponse::Ok().json(User { id: *path, name: "Alice".to_string() })
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
#[actix_web::main]
|
|
197
|
-
async fn main() -> std::io::Result<()> {
|
|
198
|
-
HttpServer::new(|| {
|
|
199
|
-
App::new()
|
|
200
|
-
.route("/users/{id}", web::get().to(get_user))
|
|
201
|
-
})
|
|
202
|
-
.bind("127.0.0.1:8080")?
|
|
203
|
-
.run()
|
|
204
|
-
.await
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## CLI 工具
|
|
209
|
-
|
|
210
|
-
### Clap
|
|
211
|
-
```rust
|
|
212
|
-
use clap::{Parser, Subcommand};
|
|
213
|
-
|
|
214
|
-
#[derive(Parser)]
|
|
215
|
-
#[command(name = "myapp")]
|
|
216
|
-
#[command(about = "My CLI application")]
|
|
217
|
-
struct Cli {
|
|
218
|
-
#[command(subcommand)]
|
|
219
|
-
command: Commands,
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
#[derive(Subcommand)]
|
|
223
|
-
enum Commands {
|
|
224
|
-
/// Start the server
|
|
225
|
-
Serve {
|
|
226
|
-
#[arg(short, long, default_value = "8080")]
|
|
227
|
-
port: u16,
|
|
228
|
-
},
|
|
229
|
-
/// Run a task
|
|
230
|
-
Run {
|
|
231
|
-
#[arg(short, long)]
|
|
232
|
-
name: String,
|
|
233
|
-
},
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
fn main() {
|
|
237
|
-
let cli = Cli::parse();
|
|
238
|
-
|
|
239
|
-
match cli.command {
|
|
240
|
-
Commands::Serve { port } => {
|
|
241
|
-
println!("Starting server on port {}", port);
|
|
242
|
-
}
|
|
243
|
-
Commands::Run { name } => {
|
|
244
|
-
println!("Running task: {}", name);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## 测试
|
|
251
|
-
|
|
252
|
-
```rust
|
|
253
|
-
#[cfg(test)]
|
|
254
|
-
mod tests {
|
|
255
|
-
use super::*;
|
|
256
|
-
|
|
257
|
-
#[test]
|
|
258
|
-
fn test_add() {
|
|
259
|
-
assert_eq!(add(1, 2), 3);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
#[test]
|
|
263
|
-
#[should_panic(expected = "divide by zero")]
|
|
264
|
-
fn test_divide_by_zero() {
|
|
265
|
-
divide(1, 0);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
#[tokio::test]
|
|
269
|
-
async fn test_async_fetch() {
|
|
270
|
-
let result = fetch_data().await;
|
|
271
|
-
assert!(result.is_ok());
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
cargo test
|
|
278
|
-
cargo test --release
|
|
279
|
-
cargo test -- --nocapture # 显示输出
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## 项目结构
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
myproject/
|
|
286
|
-
├── Cargo.toml
|
|
287
|
-
├── src/
|
|
288
|
-
│ ├── main.rs
|
|
289
|
-
│ ├── lib.rs
|
|
290
|
-
│ ├── models/
|
|
291
|
-
│ │ └── mod.rs
|
|
292
|
-
│ └── utils/
|
|
293
|
-
│ └── mod.rs
|
|
294
|
-
├── tests/
|
|
295
|
-
│ └── integration_test.rs
|
|
296
|
-
└── benches/
|
|
297
|
-
└── benchmark.rs
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
## 常用库
|
|
301
|
-
|
|
302
|
-
| 库 | 用途 |
|
|
303
|
-
|---|------|
|
|
304
|
-
| tokio | 异步运行时 |
|
|
305
|
-
| axum/actix-web | Web 框架 |
|
|
306
|
-
| serde | 序列化 |
|
|
307
|
-
| reqwest | HTTP 客户端 |
|
|
308
|
-
| sqlx | 数据库 |
|
|
309
|
-
| clap | CLI |
|
|
310
|
-
| tracing | 日志 |
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
1
|
+
---
|
|
2
|
+
name: rust
|
|
3
|
+
description: Rust 开发。系统编程、内存安全、高性能、WebAssembly。当用户提到 Rust、Cargo、tokio、内存安全时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 📜 符箓秘典 · Rust
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## 基础语法
|
|
10
|
+
|
|
11
|
+
### 所有权系统
|
|
12
|
+
```rust
|
|
13
|
+
fn main() {
|
|
14
|
+
// 所有权转移
|
|
15
|
+
let s1 = String::from("hello");
|
|
16
|
+
let s2 = s1; // s1 不再有效
|
|
17
|
+
// println!("{}", s1); // 编译错误
|
|
18
|
+
|
|
19
|
+
// 借用
|
|
20
|
+
let s3 = String::from("world");
|
|
21
|
+
let len = calculate_length(&s3); // 借用
|
|
22
|
+
println!("{} has length {}", s3, len); // s3 仍有效
|
|
23
|
+
|
|
24
|
+
// 可变借用
|
|
25
|
+
let mut s4 = String::from("hello");
|
|
26
|
+
change(&mut s4);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fn calculate_length(s: &String) -> usize {
|
|
30
|
+
s.len()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn change(s: &mut String) {
|
|
34
|
+
s.push_str(", world");
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 结构体与枚举
|
|
39
|
+
```rust
|
|
40
|
+
// 结构体
|
|
41
|
+
struct User {
|
|
42
|
+
name: String,
|
|
43
|
+
email: String,
|
|
44
|
+
active: bool,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
impl User {
|
|
48
|
+
fn new(name: String, email: String) -> Self {
|
|
49
|
+
Self { name, email, active: true }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn deactivate(&mut self) {
|
|
53
|
+
self.active = false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 枚举
|
|
58
|
+
enum Result<T, E> {
|
|
59
|
+
Ok(T),
|
|
60
|
+
Err(E),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
enum Message {
|
|
64
|
+
Quit,
|
|
65
|
+
Move { x: i32, y: i32 },
|
|
66
|
+
Write(String),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 模式匹配
|
|
70
|
+
fn handle_message(msg: Message) {
|
|
71
|
+
match msg {
|
|
72
|
+
Message::Quit => println!("Quit"),
|
|
73
|
+
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
|
|
74
|
+
Message::Write(text) => println!("Write: {}", text),
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 错误处理
|
|
80
|
+
```rust
|
|
81
|
+
use std::fs::File;
|
|
82
|
+
use std::io::{self, Read};
|
|
83
|
+
|
|
84
|
+
// Result 处理
|
|
85
|
+
fn read_file(path: &str) -> Result<String, io::Error> {
|
|
86
|
+
let mut file = File::open(path)?; // ? 操作符
|
|
87
|
+
let mut contents = String::new();
|
|
88
|
+
file.read_to_string(&mut contents)?;
|
|
89
|
+
Ok(contents)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 自定义错误
|
|
93
|
+
#[derive(Debug)]
|
|
94
|
+
enum AppError {
|
|
95
|
+
IoError(io::Error),
|
|
96
|
+
ParseError(String),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
impl From<io::Error> for AppError {
|
|
100
|
+
fn from(err: io::Error) -> Self {
|
|
101
|
+
AppError::IoError(err)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 异步编程
|
|
107
|
+
|
|
108
|
+
### Tokio
|
|
109
|
+
```rust
|
|
110
|
+
use tokio;
|
|
111
|
+
|
|
112
|
+
#[tokio::main]
|
|
113
|
+
async fn main() {
|
|
114
|
+
let result = fetch_data().await;
|
|
115
|
+
println!("{:?}", result);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async fn fetch_data() -> Result<String, reqwest::Error> {
|
|
119
|
+
let resp = reqwest::get("https://api.example.com/data")
|
|
120
|
+
.await?
|
|
121
|
+
.text()
|
|
122
|
+
.await?;
|
|
123
|
+
Ok(resp)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 并发执行
|
|
127
|
+
async fn fetch_all(urls: Vec<&str>) -> Vec<String> {
|
|
128
|
+
let futures: Vec<_> = urls.iter()
|
|
129
|
+
.map(|url| fetch_url(url))
|
|
130
|
+
.collect();
|
|
131
|
+
|
|
132
|
+
futures::future::join_all(futures).await
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Channel
|
|
136
|
+
use tokio::sync::mpsc;
|
|
137
|
+
|
|
138
|
+
async fn channel_example() {
|
|
139
|
+
let (tx, mut rx) = mpsc::channel(32);
|
|
140
|
+
|
|
141
|
+
tokio::spawn(async move {
|
|
142
|
+
tx.send("hello").await.unwrap();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
while let Some(msg) = rx.recv().await {
|
|
146
|
+
println!("Received: {}", msg);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Web 框架
|
|
152
|
+
|
|
153
|
+
### Axum
|
|
154
|
+
```rust
|
|
155
|
+
use axum::{
|
|
156
|
+
routing::{get, post},
|
|
157
|
+
Router, Json, extract::Path,
|
|
158
|
+
};
|
|
159
|
+
use serde::{Deserialize, Serialize};
|
|
160
|
+
|
|
161
|
+
#[derive(Serialize, Deserialize)]
|
|
162
|
+
struct User {
|
|
163
|
+
id: u64,
|
|
164
|
+
name: String,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async fn get_user(Path(id): Path<u64>) -> Json<User> {
|
|
168
|
+
Json(User { id, name: "Alice".to_string() })
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async fn create_user(Json(user): Json<User>) -> Json<User> {
|
|
172
|
+
Json(user)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#[tokio::main]
|
|
176
|
+
async fn main() {
|
|
177
|
+
let app = Router::new()
|
|
178
|
+
.route("/users/:id", get(get_user))
|
|
179
|
+
.route("/users", post(create_user));
|
|
180
|
+
|
|
181
|
+
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
|
182
|
+
.serve(app.into_make_service())
|
|
183
|
+
.await
|
|
184
|
+
.unwrap();
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Actix-web
|
|
189
|
+
```rust
|
|
190
|
+
use actix_web::{web, App, HttpServer, HttpResponse};
|
|
191
|
+
|
|
192
|
+
async fn get_user(path: web::Path<u64>) -> HttpResponse {
|
|
193
|
+
HttpResponse::Ok().json(User { id: *path, name: "Alice".to_string() })
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
#[actix_web::main]
|
|
197
|
+
async fn main() -> std::io::Result<()> {
|
|
198
|
+
HttpServer::new(|| {
|
|
199
|
+
App::new()
|
|
200
|
+
.route("/users/{id}", web::get().to(get_user))
|
|
201
|
+
})
|
|
202
|
+
.bind("127.0.0.1:8080")?
|
|
203
|
+
.run()
|
|
204
|
+
.await
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## CLI 工具
|
|
209
|
+
|
|
210
|
+
### Clap
|
|
211
|
+
```rust
|
|
212
|
+
use clap::{Parser, Subcommand};
|
|
213
|
+
|
|
214
|
+
#[derive(Parser)]
|
|
215
|
+
#[command(name = "myapp")]
|
|
216
|
+
#[command(about = "My CLI application")]
|
|
217
|
+
struct Cli {
|
|
218
|
+
#[command(subcommand)]
|
|
219
|
+
command: Commands,
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
#[derive(Subcommand)]
|
|
223
|
+
enum Commands {
|
|
224
|
+
/// Start the server
|
|
225
|
+
Serve {
|
|
226
|
+
#[arg(short, long, default_value = "8080")]
|
|
227
|
+
port: u16,
|
|
228
|
+
},
|
|
229
|
+
/// Run a task
|
|
230
|
+
Run {
|
|
231
|
+
#[arg(short, long)]
|
|
232
|
+
name: String,
|
|
233
|
+
},
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
fn main() {
|
|
237
|
+
let cli = Cli::parse();
|
|
238
|
+
|
|
239
|
+
match cli.command {
|
|
240
|
+
Commands::Serve { port } => {
|
|
241
|
+
println!("Starting server on port {}", port);
|
|
242
|
+
}
|
|
243
|
+
Commands::Run { name } => {
|
|
244
|
+
println!("Running task: {}", name);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## 测试
|
|
251
|
+
|
|
252
|
+
```rust
|
|
253
|
+
#[cfg(test)]
|
|
254
|
+
mod tests {
|
|
255
|
+
use super::*;
|
|
256
|
+
|
|
257
|
+
#[test]
|
|
258
|
+
fn test_add() {
|
|
259
|
+
assert_eq!(add(1, 2), 3);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#[test]
|
|
263
|
+
#[should_panic(expected = "divide by zero")]
|
|
264
|
+
fn test_divide_by_zero() {
|
|
265
|
+
divide(1, 0);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
#[tokio::test]
|
|
269
|
+
async fn test_async_fetch() {
|
|
270
|
+
let result = fetch_data().await;
|
|
271
|
+
assert!(result.is_ok());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
cargo test
|
|
278
|
+
cargo test --release
|
|
279
|
+
cargo test -- --nocapture # 显示输出
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 项目结构
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
myproject/
|
|
286
|
+
├── Cargo.toml
|
|
287
|
+
├── src/
|
|
288
|
+
│ ├── main.rs
|
|
289
|
+
│ ├── lib.rs
|
|
290
|
+
│ ├── models/
|
|
291
|
+
│ │ └── mod.rs
|
|
292
|
+
│ └── utils/
|
|
293
|
+
│ └── mod.rs
|
|
294
|
+
├── tests/
|
|
295
|
+
│ └── integration_test.rs
|
|
296
|
+
└── benches/
|
|
297
|
+
└── benchmark.rs
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## 常用库
|
|
301
|
+
|
|
302
|
+
| 库 | 用途 |
|
|
303
|
+
|---|------|
|
|
304
|
+
| tokio | 异步运行时 |
|
|
305
|
+
| axum/actix-web | Web 框架 |
|
|
306
|
+
| serde | 序列化 |
|
|
307
|
+
| reqwest | HTTP 客户端 |
|
|
308
|
+
| sqlx | 数据库 |
|
|
309
|
+
| clap | CLI |
|
|
310
|
+
| tracing | 日志 |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|