{{ talk_to_me_lang }}
Here is the refined, concise English version of your guidelines for AI:
Salvo Framework Overview
Salvo is a Rust-based web framework focused on simplicity, efficiency, and usability. Key concepts include Router, Handler, Middleware, Request, Response, and Depot.
Key Concepts:
1. Router:
• Create with Router::new().
• Define paths with path() or with_path().
• Use HTTP methods like get(), post(), patch(), delete().
• Support for path parameters (e.g., {id}, <id:num>).
• Filters like filters::path(), filters::get() can be added.
• Add middleware with hoop().
2. Handler:
• Use #[handler] macro for easy definition.
• Optional parameters include Request, Depot, FlowCtrl.
• Return types must implement Writer Trait (e.g., &str, String, Result<T, E>).
3. Middleware:
• Implement Handler Trait.
• Use hoop() to add middleware to Router or Service.
• Control execution flow with FlowCtrl, e.g., ctrl.skip_rest().
4. Request:
• Get path parameters with req.param::<T>("param_name").
• Use req.query::<T>("query_name") for query parameters.
• Parse form or JSON with req.form::<T>("name").await or req.parse_json::<T>().await.
• Extract data into structures with req.extract().
5. Response:
• Render responses with res.render().
• Return types like Text::Plain(), Text::Html(), Json().
• Set status with res.status_code() or StatusError.
• Use Redirect::found() for redirection.
6. Depot:
• Store temporary data between middleware and handlers with methods like depot.insert() and depot.obtain::<T>().
7. Extractors:
• Use #[salvo(extract(...))] annotations to map request data to structures.
Core Features:
• Static File Serving: Use StaticDir or StaticEmbed.
• OpenAPI Support: Auto-generate docs with #[endpoint] macro.
Routing:
• Flat or tree-like route structure supported.
Middleware:
• Middleware is a Handler added to Router, Service, or Catcher.
• FlowCtrl allows skipping handlers or middleware.
Error Handling:
• Handlers return Result<T, E> where T and E implement Writer Trait.
• Custom errors are handled via the Writer Trait, with anyhow::Error as the default.
Deployment:
• Compile Salvo apps into a single executable for easy deployment.
Project Structure:
project/
├── src/
│ ├── routers/
│ ├── models/
│ ├── db/
│ ├── error.rs
│ └── utils.rs
├── views/
│ └── *.html
├── migrations/
└── assets/
├── js/
└── css/
JSON Response Format:
#[derive(Serialize)]
pub struct JsonResponse<T> {
pub code: i32,
pub message: String,
pub data: T,
}
Frontend Guidelines:
1. Tailwind CSS:
• Use flex, grid, space-x, space-y, bg-{color}, text-{color}, rounded-{size}, shadow-{size}.
2. Alpine.js:
• Use x-data, x-model, @click, x-show, x-if.
3. Fragment Architecture:
• Use X-Fragment-Header for partial page updates via x-html.
Error Handling:
• AppError handles various error types: Public, Internal, HttpStatus, SqlxError, Validation.
• Log errors with tracing and return appropriate HTTP status codes.
Database Operations:
• Use SQLx for async DB operations (e.g., query!, query_as!).
• Paginate with LIMIT and OFFSET.
Password Handling:
• Use bcrypt/Argon2 for password hashing.
Input Validation:
• Use validator for validating and sanitizing inputs.
Diesel ORM Guidelines:
1. Database Connection Setup:
{%- if db_type == "postgres" %}
• PostgreSQL:
- URL format: postgres://user:password@host:port/dbname
- Enable features: diesel/postgres
- Types: Timestamp, Uuid, Json/Jsonb support
{%- endif %}
{%- if db_type == "mysql" %}
• MySQL:
- URL format: mysql://user:password@host/dbname
- Enable features: diesel/mysql
- Types: DateTime for timestamps
{%- endif %}
{%- if db_type == "sqlite" %}
• SQLite:
- URL format: file:path/to/db.sqlite
- Enable features: diesel/sqlite
- Types: INTEGER for auto-increment
{%- endif %}
2. Schema Definition:
```rust
diesel::table! {
users (id) {
id -> Text,
username -> Text,
password -> Text,
}
}
```
3. Model Definition:
```rust
#[derive(Queryable, Selectable, Insertable)]
#[diesel(table_name = users)]
pub struct User {
pub id: String,
pub username: String,
pub password: String,
}
```
4. Common Operations:
• Select:
```rust
users::table.filter(users::id.eq(user_id)).first::<User>(conn)?
```
• Insert:
```rust
diesel::insert_into(users::table).values(&user).execute(conn)?
```
• Update:
```rust
diesel::update(users::table)
.filter(users::id.eq(user_id))
.set(users::username.eq(new_username))
.execute(conn)?
```
• Delete:
```rust
diesel::delete(users::table).filter(users::id.eq(user_id)).execute(conn)?
```
5. Relationships:
• belongs_to:
```rust
#[derive(Associations)]
#[belongs_to(User)]
pub struct Post { ... }
```
• has_many: Use inner joins
```rust
users::table.inner_join(posts::table)
```
6. Migrations:
• Create: diesel migration generate create_users
• Run: diesel migration run
• Revert: diesel migration revert
7. Database-Specific Features:
{%- if db_type == "postgres" %}
• PostgreSQL:
- JSONB operations
- Full-text search
- Array types
{%- endif %}
{%- if db_type == "mysql" %}
• MySQL:
- ON DUPLICATE KEY
- REPLACE INTO
{%- endif %}
{%- if db_type == "sqlite" %}
• SQLite:
- Simple file-based
- WAL mode for concurrency
{%- endif %}
8. Best Practices:
• Use connection pools (r2d2)
• Implement From/Into for models
• Use transactions for atomic operations
• Use derive macros for boilerplate
golang
liquid
mysql
postgresql
rest-api
rust
sqlite
tailwindcss