Skip to content

Commit af0a254

Browse files
committed
update: cms
1 parent dab5be4 commit af0a254

File tree

5 files changed

+149
-94
lines changed

5 files changed

+149
-94
lines changed

Taskfile.yml

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ tasks:
7070
cmds:
7171
- cargo install sea-orm-cli
7272
- sea-orm-cli -h
73+
- cargo install cargo-watch
7374

7475
install:
7576
cmds:

crates/rs-cms/readme.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,24 @@ DATABASE_URL=postgres://username:password@localhost/diesel_demo
3535

3636
- run:
3737

38-
```rust shell
38+
```rust shell
3939

4040
# install:
41-
task install
41+
task install
4242

4343
# set db env:
44-
task init:env
44+
task init:env
4545

4646
# create db:
4747
task db:setup
48-
task db:init
48+
task db:init
4949

5050
# run:
5151
task run
5252

53+
# run with auto watch:
54+
task watch
55+
5356
```
5457

5558
## reference:
@@ -75,4 +78,3 @@ task run
7578
- https://www.cnblogs.com/rongfengliang/p/12256614.html
7679
- https://www.ancii.com/ab3q5edb5/
7780
- https://github.com/diesel-rs/diesel/blob/master/examples/mysql/getting_started_step_1/src/schema.rs
78-

crates/rs-cms/src/main.rs

+7-89
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use axum::{
2424
};
2525
use dotenvy::dotenv;
2626
// use log::{debug, info, warn};
27+
use crate::service::hello;
2728
use pretty_env_logger;
2829
use serde::{Deserialize, Serialize};
2930
use std::{
@@ -36,6 +37,7 @@ use std::{
3637
use tower::{BoxError, ServiceBuilder};
3738
use tower_http::trace::TraceLayer;
3839
use uuid::Uuid;
40+
mod service;
3941
mod utils;
4042
use crate::utils::{route, shutdown};
4143
use tracing::{debug, error, info, warn, Level};
@@ -63,15 +65,15 @@ async fn main() {
6365

6466
// fix conflict with tracing_subscriber
6567
// pretty_env_logger::init_custom_env("CMS_LOG");
66-
67-
let db = Db::default();
68+
let db = hello::Db::default();
6869

6970
// Compose the routes
7071
let app = Router::new()
7172
.fallback(route::handler_404.into_service())
72-
.route("/", get(todos_index).post(todos_create))
73-
.route("/todos", get(todos_index).post(todos_create))
74-
.route("/todos/:id", patch(todos_update).delete(todos_delete))
73+
.route("/", get(hello::hello))
74+
.route("/index", get(hello::todos_index).post(hello::todos_create))
75+
.route("/todos", get(hello::todos_index).post(hello::todos_create))
76+
.route("/todos/:id", patch(hello::todos_update).delete(hello::todos_delete))
7577
// Add middleware to all routes
7678
.layer(
7779
ServiceBuilder::new()
@@ -106,87 +108,3 @@ async fn main() {
106108
.await
107109
.unwrap();
108110
}
109-
110-
// The query parameters for todos index
111-
#[derive(Debug, Deserialize, Default)]
112-
pub struct Pagination {
113-
pub offset: Option<usize>,
114-
pub limit: Option<usize>,
115-
}
116-
117-
async fn todos_index(
118-
pagination: Option<Query<Pagination>>,
119-
Extension(db): Extension<Db>,
120-
) -> impl IntoResponse {
121-
let todos = db.read().unwrap();
122-
123-
let Query(pagination) = pagination.unwrap_or_default();
124-
125-
let todos = todos
126-
.values()
127-
.skip(pagination.offset.unwrap_or(0))
128-
.take(pagination.limit.unwrap_or(usize::MAX))
129-
.cloned()
130-
.collect::<Vec<_>>();
131-
132-
Json(todos)
133-
}
134-
135-
#[derive(Debug, Deserialize)]
136-
struct CreateTodo {
137-
text: String,
138-
}
139-
140-
async fn todos_create(
141-
Json(input): Json<CreateTodo>,
142-
Extension(db): Extension<Db>,
143-
) -> impl IntoResponse {
144-
let todo = Todo { id: Uuid::new_v4(), text: input.text, completed: false };
145-
146-
db.write().unwrap().insert(todo.id, todo.clone());
147-
148-
(StatusCode::CREATED, Json(todo))
149-
}
150-
151-
#[derive(Debug, Deserialize)]
152-
struct UpdateTodo {
153-
text: Option<String>,
154-
completed: Option<bool>,
155-
}
156-
157-
async fn todos_update(
158-
Path(id): Path<Uuid>,
159-
Json(input): Json<UpdateTodo>,
160-
Extension(db): Extension<Db>,
161-
) -> Result<impl IntoResponse, StatusCode> {
162-
let mut todo = db.read().unwrap().get(&id).cloned().ok_or(StatusCode::NOT_FOUND)?;
163-
164-
if let Some(text) = input.text {
165-
todo.text = text;
166-
}
167-
168-
if let Some(completed) = input.completed {
169-
todo.completed = completed;
170-
}
171-
172-
db.write().unwrap().insert(todo.id, todo.clone());
173-
174-
Ok(Json(todo))
175-
}
176-
177-
async fn todos_delete(Path(id): Path<Uuid>, Extension(db): Extension<Db>) -> impl IntoResponse {
178-
if db.write().unwrap().remove(&id).is_some() {
179-
StatusCode::NO_CONTENT
180-
} else {
181-
StatusCode::NOT_FOUND
182-
}
183-
}
184-
185-
type Db = Arc<RwLock<HashMap<Uuid, Todo>>>;
186-
187-
#[derive(Debug, Serialize, Clone)]
188-
struct Todo {
189-
id: Uuid,
190-
text: String,
191-
completed: bool,
192-
}

crates/rs-cms/src/service/hello.rs

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//! Provides a RESTful web server managing some Todos.
2+
//!
3+
//! API will be:
4+
//!
5+
//! - `GET /todos`: return a JSON list of Todos.
6+
//! - `POST /todos`: create a new Todo.
7+
//! - `PUT /todos/:id`: update a specific Todo.
8+
//! - `DELETE /todos/:id`: delete a specific Todo.
9+
//!
10+
//! Run with
11+
//!
12+
//! ```not_rust
13+
//! cargo run -p example-todos
14+
//! ```
15+
16+
use axum::{
17+
error_handling::HandleErrorLayer,
18+
extract::{Extension, Path, Query},
19+
handler::Handler,
20+
http::StatusCode,
21+
response::IntoResponse,
22+
routing::{get, patch},
23+
Json, Router,
24+
};
25+
26+
use serde::{Deserialize, Serialize};
27+
use std::{
28+
collections::HashMap,
29+
env,
30+
net::SocketAddr,
31+
sync::{Arc, RwLock},
32+
time::Duration,
33+
};
34+
use tower::{BoxError, ServiceBuilder};
35+
use tower_http::trace::TraceLayer;
36+
use uuid::Uuid;
37+
38+
use crate::utils::{route, shutdown};
39+
use tracing::{debug, error, info, warn, Level};
40+
41+
#[derive(Debug, Deserialize, Serialize)]
42+
pub struct Message {
43+
msg: String,
44+
status: String,
45+
}
46+
pub async fn hello() -> impl IntoResponse {
47+
let result = Message { msg: "hello world".into(), status: "ok".into() };
48+
Json(result)
49+
}
50+
51+
// The query parameters for todos index
52+
#[derive(Debug, Deserialize, Default)]
53+
pub struct Pagination {
54+
pub offset: Option<usize>,
55+
pub limit: Option<usize>,
56+
}
57+
58+
pub async fn todos_index(
59+
pagination: Option<Query<Pagination>>,
60+
Extension(db): Extension<Db>,
61+
) -> impl IntoResponse {
62+
let todos = db.read().unwrap();
63+
64+
let Query(pagination) = pagination.unwrap_or_default();
65+
66+
let todos = todos
67+
.values()
68+
.skip(pagination.offset.unwrap_or(0))
69+
.take(pagination.limit.unwrap_or(usize::MAX))
70+
.cloned()
71+
.collect::<Vec<_>>();
72+
73+
Json(todos)
74+
}
75+
76+
#[derive(Debug, Deserialize)]
77+
pub struct CreateTodo {
78+
text: String,
79+
}
80+
81+
pub async fn todos_create(
82+
Json(input): Json<CreateTodo>,
83+
Extension(db): Extension<Db>,
84+
) -> impl IntoResponse {
85+
let todo = Todo { id: Uuid::new_v4(), text: input.text, completed: false };
86+
87+
db.write().unwrap().insert(todo.id, todo.clone());
88+
89+
(StatusCode::CREATED, Json(todo))
90+
}
91+
92+
#[derive(Debug, Deserialize)]
93+
pub struct UpdateTodo {
94+
text: Option<String>,
95+
completed: Option<bool>,
96+
}
97+
98+
pub async fn todos_update(
99+
Path(id): Path<Uuid>,
100+
Json(input): Json<UpdateTodo>,
101+
Extension(db): Extension<Db>,
102+
) -> Result<impl IntoResponse, StatusCode> {
103+
let mut todo = db.read().unwrap().get(&id).cloned().ok_or(StatusCode::NOT_FOUND)?;
104+
105+
if let Some(text) = input.text {
106+
todo.text = text;
107+
}
108+
109+
if let Some(completed) = input.completed {
110+
todo.completed = completed;
111+
}
112+
113+
db.write().unwrap().insert(todo.id, todo.clone());
114+
115+
Ok(Json(todo))
116+
}
117+
118+
pub async fn todos_delete(Path(id): Path<Uuid>, Extension(db): Extension<Db>) -> impl IntoResponse {
119+
if db.write().unwrap().remove(&id).is_some() {
120+
StatusCode::NO_CONTENT
121+
} else {
122+
StatusCode::NOT_FOUND
123+
}
124+
}
125+
126+
pub(crate) type Db = Arc<RwLock<HashMap<Uuid, Todo>>>;
127+
128+
#[derive(Debug, Serialize, Clone)]
129+
pub struct Todo {
130+
id: Uuid,
131+
text: String,
132+
completed: bool,
133+
}

crates/rs-cms/src/service/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod hello;

0 commit comments

Comments
 (0)