Add dev prompts for keyword, model, and service
This commit is contained in:
parent
44d4a7b392
commit
83d4a61fcd
4 changed files with 337 additions and 0 deletions
151
prompts/dev/add-keyword.md
Normal file
151
prompts/dev/add-keyword.md
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
Create a new Rhai custom keyword implementation with these specifications:
|
||||
|
||||
- When generating new Rhai keyword handlers in Rust, always design them to be thread-safe and fully compatible with async execution. Use Arc for shared state, perform heavy or async operations with tokio::task::block_in_place and Handle::current().block_on, and return results as rhai::Dynamic to maintain safe cross-thread communication between Rust and the Rhai engine.
|
||||
|
||||
1. DATABASE REQUIREMENTS:
|
||||
- No enums in database schema (only in Rust code)
|
||||
- Use direct integer values for enum variants in queries
|
||||
- Follow existing connection pooling pattern with AppState
|
||||
- Include proper error handling and logging
|
||||
|
||||
2. RUST IMPLEMENTATION:
|
||||
- Enum definition (Rust-only, no DB enum):
|
||||
```rust
|
||||
#[repr(i32)]
|
||||
pub enum KeywordAction {
|
||||
Action1 = 0,
|
||||
Action2 = 1,
|
||||
Action3 = 2
|
||||
}
|
||||
```
|
||||
|
||||
3. KEYWORD TEMPLATE:
|
||||
```rust
|
||||
pub fn {keyword_name}_keyword(state: &AppState, engine: &mut Engine) {
|
||||
let db = state.db_custom.clone();
|
||||
|
||||
engine.register_custom_syntax(
|
||||
{syntax_pattern},
|
||||
{is_raw},
|
||||
{
|
||||
let db = db.clone();
|
||||
move |context, inputs| {
|
||||
// Input processing
|
||||
{input_processing}
|
||||
|
||||
let binding = db.as_ref().unwrap();
|
||||
let fut = execute_{keyword_name}(binding, {params});
|
||||
|
||||
let result = tokio::task::block_in_place(||
|
||||
tokio::runtime::Handle::current().block_on(fut))
|
||||
.map_err(|e| format!("DB error: {}", e))?;
|
||||
|
||||
{result_handling}
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
pub async fn execute_{keyword_name}(
|
||||
pool: &PgPool,
|
||||
{params_with_types}
|
||||
) -> Result<Value, Box<dyn std::error::Error>> {
|
||||
info!("Executing {keyword_name} with: {debug_params}");
|
||||
|
||||
let result = sqlx::query(
|
||||
"{sql_query_with_i32_enum}"
|
||||
)
|
||||
.bind({enum_value} as i32)
|
||||
{additional_binds}
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(json!({
|
||||
"command": "{keyword_name}",
|
||||
{result_fields}
|
||||
"rows_affected": result.rows_affected()
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
4. EXAMPLE IMPLEMENTATION (SET SCHEDULE):
|
||||
```rust
|
||||
// Enum (Rust-only)
|
||||
#[repr(i32)]
|
||||
pub enum TriggerKind {
|
||||
Scheduled = 0,
|
||||
TableUpdate = 1,
|
||||
TableInsert = 2,
|
||||
TableDelete = 3
|
||||
}
|
||||
|
||||
// Keyword implementation
|
||||
pub fn set_schedule_keyword(state: &AppState, engine: &mut Engine) {
|
||||
let db = state.db_custom.clone();
|
||||
|
||||
engine.register_custom_syntax(
|
||||
["SET", "SCHEDULE", "$string$"],
|
||||
true,
|
||||
{
|
||||
let db = db.clone();
|
||||
move |context, inputs| {
|
||||
let cron = context.eval_expression_tree(&inputs[0])?.to_string();
|
||||
let script_name = format!("cron_{}.rhai", cron.replace(' ', "_"));
|
||||
|
||||
let binding = db.as_ref().unwrap();
|
||||
let fut = execute_set_schedule(binding, &cron, &script_name);
|
||||
|
||||
let result = tokio::task::block_in_place(||
|
||||
tokio::runtime::Handle::current().block_on(fut))
|
||||
.map_err(|e| format!("DB error: {}", e))?;
|
||||
|
||||
if let Some(rows_affected) = result.get("rows_affected") {
|
||||
Ok(Dynamic::from(rows_affected.as_i64().unwrap_or(0)))
|
||||
} else {
|
||||
Err("No rows affected".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
pub async fn execute_set_schedule(
|
||||
pool: &PgPool,
|
||||
cron: &str,
|
||||
script_name: &str,
|
||||
) -> Result<Value, Box<dyn std::error::Error>> {
|
||||
info!("Executing schedule: {}, {}", cron, script_name);
|
||||
|
||||
let result = sqlx::query(
|
||||
"INSERT INTO system_automations
|
||||
(kind, schedule, script_name)
|
||||
VALUES ($1, $2, $3)"
|
||||
)
|
||||
.bind(TriggerKind::Scheduled as i32)
|
||||
.bind(cron)
|
||||
.bind(script_name)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(json!({
|
||||
"command": "set_schedule",
|
||||
"schedule": cron,
|
||||
"script_name": script_name,
|
||||
"rows_affected": result.rows_affected()
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
5. ADDITIONAL REQUIREMENTS:
|
||||
- Maintain consistent tokio runtime handling
|
||||
- Include parameter validation
|
||||
- Follow existing JSON response format
|
||||
- Ensure proper script name generation
|
||||
- Include debug logging for all operations
|
||||
|
||||
6. OUTPUT FORMAT:
|
||||
Provide complete implementation with:
|
||||
1. Rust enum definition
|
||||
2. Keyword registration function
|
||||
3. Execution function
|
||||
4. Example usage in Rhai
|
||||
94
prompts/dev/add-model.md
Normal file
94
prompts/dev/add-model.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
Create a Rust data model for database storage with optimal size and performance characteristics. Follow these specifications:
|
||||
|
||||
**REQUIREMENTS:**
|
||||
1. Use appropriate integer types (i32, i16, i8, etc.) based on expected value ranges
|
||||
2. Use `Option<T>` for nullable fields to avoid memory overhead
|
||||
3. Use `Vec<u8>` for binary data instead of strings when appropriate
|
||||
4. Prefer enum representations as integers rather than strings
|
||||
5. Use `chrono::DateTime<Utc>` for timestamps
|
||||
6. Use `uuid::Uuid` for unique identifiers
|
||||
7. Implement necessary traits: `Debug`, `Clone`, `Serialize`, `Deserialize`, `FromRow`
|
||||
8. Include validation where appropriate
|
||||
9. Consider database index strategy in field design
|
||||
|
||||
**CONTEXT:**
|
||||
- Database: PostgreSQL/SQLx compatible
|
||||
- Serialization: Serde for JSON
|
||||
- ORM: SQLx for database operations
|
||||
|
||||
**OUTPUT FORMAT:**
|
||||
Provide the complete Rust struct with:
|
||||
- Struct definition with fields
|
||||
- Enum definitions with integer representations
|
||||
- Conversion implementations
|
||||
- Basic validation if needed
|
||||
|
||||
**EXAMPLE REFERENCE:**
|
||||
```rust
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::FromRow;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Status {
|
||||
Pending = 0,
|
||||
Active = 1,
|
||||
Inactive = 2,
|
||||
}
|
||||
|
||||
impl Status {
|
||||
pub fn from_i16(value: i16) -> Option<Self> {
|
||||
match value {
|
||||
0 => Some(Self::Pending),
|
||||
1 => Some(Self::Active),
|
||||
2 => Some(Self::Inactive),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromRow, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
pub id: Uuid,
|
||||
pub status: i16, // Using i16 for enum storage
|
||||
pub email: String,
|
||||
pub age: Option<i16>, // Nullable small integer
|
||||
pub metadata: Vec<u8>, // Binary data for flexibility
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
```
|
||||
|
||||
Generate a similar model for: [YOUR DOMAIN HERE]
|
||||
```
|
||||
|
||||
## Specialized Variants
|
||||
|
||||
### For High-Performance Applications
|
||||
```
|
||||
Add these additional requirements:
|
||||
- Use `#[repr(u8)]` for enums to ensure minimal size
|
||||
- Consider `Box<str>` instead of `String` for reduced heap overhead
|
||||
- Use `arrayvec::ArrayString` for fixed-size short strings
|
||||
- Implement `PartialEq` and `Eq` for hash-based operations
|
||||
- Include `#[derive(Default)]` where appropriate
|
||||
```
|
||||
|
||||
### For Embedded/Memory-Constrained Systems
|
||||
```
|
||||
Add these constraints:
|
||||
- Prefer `i16` over `i32` where possible
|
||||
- Use `u32` instead of `Uuid` if sequential IDs are acceptable
|
||||
- Consider `bitflags` for multiple boolean flags in single byte
|
||||
- Use `smol_str::SmolStr` for string optimization
|
||||
- Avoid `Vec` in favor of arrays with capacity limits
|
||||
```
|
||||
|
||||
### For Time-Series Data
|
||||
```
|
||||
Add time-series specific optimizations:
|
||||
- Use `i64` for timestamps as nanoseconds since epoch
|
||||
- Use `f32` instead of `f64` for measurements where precision allows
|
||||
- Consider `ordered_float::OrderedFloat` for floating-point comparisons
|
||||
- Use `#[serde(with = "chrono::serde::ts_seconds")]` for compact serialization
|
||||
57
prompts/dev/add-service.md
Normal file
57
prompts/dev/add-service.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
Generate a Rust service module following these patterns:
|
||||
|
||||
Core Structure:
|
||||
|
||||
Use actix-web for HTTP endpoints (get, post, etc.)
|
||||
|
||||
Isolate shared resources (DB, clients, config) in AppState
|
||||
|
||||
Split logic into reusable helper functions
|
||||
|
||||
do not create main logic
|
||||
|
||||
Endpoints:
|
||||
|
||||
Follow REST conventions (e.g., POST /{resource}/create) use anotations in methods.
|
||||
|
||||
Use web::Path for route parameters, web::Json for payloads
|
||||
|
||||
Return consistent responses (e.g., HttpResponse::Ok().json(data))
|
||||
|
||||
Error Handling:
|
||||
|
||||
Wrap fallible operations in Result
|
||||
|
||||
Use map_err to convert errors to actix_web::Error
|
||||
|
||||
Provide clear error messages (e.g., ErrorInternalServerError)
|
||||
|
||||
Async Patterns:
|
||||
|
||||
Use async/await for I/O (DB, external APIs)
|
||||
|
||||
Leverage streams for pagination/large datasets
|
||||
|
||||
Isolate blocking ops in spawn_blocking if needed
|
||||
|
||||
Configuration:
|
||||
|
||||
Load settings (e.g., URLs, credentials) from AppConfig
|
||||
|
||||
Initialize clients (DB, SDKs) at startup (e.g., init_*() helpers)
|
||||
|
||||
Documentation:
|
||||
|
||||
Add brief doc comments for public functions
|
||||
|
||||
Note safety assumptions (e.g., #[post] invariants)
|
||||
postgres sqlx
|
||||
Omit domain-specific logic (e.g., file/email details), focusing on the scaffolding."
|
||||
|
||||
Key Features:
|
||||
|
||||
Generic (applies to any service: auth, payments, etc.)
|
||||
|
||||
KISS (avoids over-engineering)
|
||||
|
||||
Copy-paste friendly (clear patterns without verbosity)
|
||||
35
prompts/dev/fix-errors.md
Normal file
35
prompts/dev/fix-errors.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
You are fixing Rust code in a Cargo project. The user is providing problematic code that needs to be corrected.
|
||||
|
||||
## Your Task
|
||||
Fix ALL compiler errors and logical issues while maintaining the original intent.
|
||||
Use Cargo.toml as reference, do not change it.
|
||||
Only return input files, all other files already exists.
|
||||
If something, need to be added to a external file, inform it separated.
|
||||
|
||||
## Critical Requirements
|
||||
3. **Respect Cargo.toml** - Check dependencies, editions, and features to avoid compiler errors
|
||||
4. **Type safety** - Ensure all types match and trait bounds are satisfied
|
||||
5. **Ownership rules** - Fix borrowing, ownership, and lifetime issues
|
||||
|
||||
|
||||
MORE RULES:
|
||||
- Return only the modified files as a single `.sh` script using `cat`, so the - code can be restored directly.
|
||||
- You MUST return exactly this example format:
|
||||
```sh
|
||||
#!/bin/bash
|
||||
|
||||
# Restore fixed Rust project
|
||||
|
||||
cat > src/<filenamehere>.rs << 'EOF'
|
||||
use std::io;
|
||||
|
||||
// test
|
||||
|
||||
cat > src/<anotherfile>.rs << 'EOF'
|
||||
// Fixed library code
|
||||
pub fn add(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
EOF
|
||||
|
||||
----
|
||||
Loading…
Add table
Reference in a new issue