salvo-rs salvo-cli .cursorrules file for Rust (stars: 46)

{{ 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

First Time Repository

Rust

Languages:

Liquid: 75.1KB
Rust: 88.3KB
Created: 9/20/2023
Updated: 1/23/2025

All Repositories (1)