veza/dev-environment/templates/rust/service_template.rs
2025-12-03 22:56:50 +01:00

190 lines
6 KiB
Rust

use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use tokio::sync::RwLock;
use tracing::{info, warn, error, debug};
use uuid::Uuid;
/// {{.ServiceName}}Service gère les fonctionnalités de {{.ServiceName}}
#[derive(Debug, Clone)]
pub struct {{.ServiceName}}Service {
// Ajoutez vos dépendances ici
data: Arc<RwLock<HashMap<String, {{.ServiceName}}Data>>>,
}
/// Données pour {{.ServiceName}}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {{.ServiceName}}Data {
pub id: String,
pub name: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: chrono::DateTime<chrono::Utc>,
}
/// Erreurs pour {{.ServiceName}}
#[derive(Debug, thiserror::Error)]
pub enum {{.ServiceName}}Error {
#[error("{{.ServiceName}} not found")]
NotFound,
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("Database error: {0}")]
DatabaseError(String),
#[error("Internal error: {0}")]
InternalError(String),
}
impl {{.ServiceName}}Service {
/// Crée une nouvelle instance du service
pub fn new() -> Self {
Self {
data: Arc::new(RwLock::new(HashMap::new())),
}
}
/// Traite les données de {{.ServiceName}}
pub async fn process_{{.ServiceName}}(&self, input: String) -> Result<String, {{.ServiceName}}Error> {
info!("Processing {{.ServiceName}} with input: {}", input);
// Implémentation de votre logique métier
let result = format!("Processed: {}", input);
info!("{{.ServiceName}} processed successfully: {}", result);
Ok(result)
}
/// Crée une nouvelle entrée
pub async fn create(&self, name: String) -> Result<{{.ServiceName}}Data, {{.ServiceName}}Error> {
info!("Creating {{.ServiceName}} with name: {}", name);
let id = Uuid::new_v4().to_string();
let now = chrono::Utc::now();
let data = {{.ServiceName}}Data {
id: id.clone(),
name,
created_at: now,
updated_at: now,
};
let mut store = self.data.write().await;
store.insert(id, data.clone());
info!("{{.ServiceName}} created successfully: {}", data.id);
Ok(data)
}
/// Récupère une entrée par ID
pub async fn get_by_id(&self, id: &str) -> Result<{{.ServiceName}}Data, {{.ServiceName}}Error> {
debug!("Getting {{.ServiceName}} by ID: {}", id);
let store = self.data.read().await;
store.get(id)
.cloned()
.ok_or({{.ServiceName}}Error::NotFound)
}
/// Met à jour une entrée existante
pub async fn update(&self, id: &str, name: String) -> Result<{{.ServiceName}}Data, {{.ServiceName}}Error> {
info!("Updating {{.ServiceName}} with ID: {}", id);
let mut store = self.data.write().await;
if let Some(data) = store.get_mut(id) {
data.name = name;
data.updated_at = chrono::Utc::now();
info!("{{.ServiceName}} updated successfully: {}", id);
Ok(data.clone())
} else {
Err({{.ServiceName}}Error::NotFound)
}
}
/// Supprime une entrée
pub async fn delete(&self, id: &str) -> Result<(), {{.ServiceName}}Error> {
info!("Deleting {{.ServiceName}} with ID: {}", id);
let mut store = self.data.write().await;
if store.remove(id).is_some() {
info!("{{.ServiceName}} deleted successfully: {}", id);
Ok(())
} else {
Err({{.ServiceName}}Error::NotFound)
}
}
/// Liste toutes les entrées
pub async fn list_all(&self) -> Result<Vec<{{.ServiceName}}Data>, {{.ServiceName}}Error> {
debug!("Listing all {{.ServiceName}} entries");
let store = self.data.read().await;
Ok(store.values().cloned().collect())
}
/// Health check pour le service
pub async fn health_check(&self) -> Result<(), {{.ServiceName}}Error> {
debug!("{{.ServiceName}} health check");
// Implémentation du health check
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_create_{{.ServiceName}}() {
let service = {{.ServiceName}}Service::new();
let result = service.create("Test {{.ServiceName}}".to_string()).await;
assert!(result.is_ok());
let data = result.unwrap();
assert_eq!(data.name, "Test {{.ServiceName}}");
}
#[tokio::test]
async fn test_get_{{.ServiceName}}_by_id() {
let service = {{.ServiceName}}Service::new();
let created = service.create("Test {{.ServiceName}}".to_string()).await.unwrap();
let result = service.get_by_id(&created.id).await;
assert!(result.is_ok());
let data = result.unwrap();
assert_eq!(data.id, created.id);
assert_eq!(data.name, "Test {{.ServiceName}}");
}
#[tokio::test]
async fn test_update_{{.ServiceName}}() {
let service = {{.ServiceName}}Service::new();
let created = service.create("Test {{.ServiceName}}".to_string()).await.unwrap();
let result = service.update(&created.id, "Updated {{.ServiceName}}".to_string()).await;
assert!(result.is_ok());
let updated = result.unwrap();
assert_eq!(updated.name, "Updated {{.ServiceName}}");
}
#[tokio::test]
async fn test_delete_{{.ServiceName}}() {
let service = {{.ServiceName}}Service::new();
let created = service.create("Test {{.ServiceName}}".to_string()).await.unwrap();
let result = service.delete(&created.id).await;
assert!(result.is_ok());
let get_result = service.get_by_id(&created.id).await;
assert!(get_result.is_err());
}
#[tokio::test]
async fn test_health_check() {
let service = {{.ServiceName}}Service::new();
let result = service.health_check().await;
assert!(result.is_ok());
}
}