veza/veza-common/README.md

373 lines
8 KiB
Markdown
Raw Permalink Normal View History

2025-12-03 21:24:14 +00:00
# Veza Common Library
Bibliothèque commune pour tous les services Veza. Cette bibliothèque fournit des types partagés, des utilitaires et des configurations communes utilisées par tous les services du projet Veza.
## Installation
Ajoutez cette dépendance à votre `Cargo.toml`:
```toml
[dependencies]
veza-common = { path = "../veza-common" }
```
## Modules
### Types (`types`)
Types de données partagés pour tous les services.
#### User
```rust
use veza_common::types::User;
let user = User::new(1, "john_doe".to_string(), "john@example.com".to_string());
assert!(user.validate().is_ok());
```
#### Track
```rust
use veza_common::types::Track;
use uuid::Uuid;
let track_id = Uuid::new_v4();
let track = Track::new(
track_id,
"Song Title".to_string(),
"Artist Name".to_string(),
180 // duration in seconds
);
assert_eq!(track.formatted_duration(), "3:00");
```
#### Playlist
```rust
use veza_common::types::Playlist;
use uuid::Uuid;
let playlist_id = Uuid::new_v4();
let owner_id = Uuid::new_v4();
let mut playlist = Playlist::new(playlist_id, "My Playlist".to_string(), owner_id);
let track_id = Uuid::new_v4();
playlist.add_track(track_id);
assert_eq!(playlist.track_count(), 1);
```
#### API Response
```rust
use veza_common::types::ApiResponse;
// Success response
let response = ApiResponse::success("data".to_string());
assert!(response.success);
// Error response
let error_response = ApiResponse::<String>::error("Error message".to_string());
assert!(!error_response.success);
```
### Error Handling (`error`)
Types d'erreurs standardisés avec codes HTTP et messages.
```rust
use veza_common::error::{CommonError, CommonResult};
fn example_function() -> CommonResult<i32> {
// Return success
Ok(42)
// Or error
// Err(CommonError::NotFound("Resource not found".to_string()))
}
// Error codes
let error = CommonError::ValidationError("Invalid input".to_string());
assert_eq!(error.code(), "VALIDATION_ERROR");
assert_eq!(error.http_status_code(), 400);
```
### Configuration (`config`)
Types de configuration pour Database et Redis.
#### DatabaseConfig
```rust
use veza_common::config::DatabaseConfig;
use std::time::Duration;
let config = DatabaseConfig::new(
"postgresql://user:password@localhost:5432/mydb".to_string(),
10 // max_connections
);
// Validate configuration
assert!(config.validate().is_ok());
// Extract information
let host = config.host(); // Some("localhost")
let port = config.port(); // Some(5432)
let db_name = config.database_name(); // Some("mydb")
```
#### RedisConfig
```rust
use veza_common::config::RedisConfig;
let config = RedisConfig::new("redis://localhost:6379".to_string());
// Validate configuration
assert!(config.validate().is_ok());
// Check SSL
let is_ssl = config.is_ssl(); // false for redis://, true for rediss://
// Extract information
let host = config.host(); // Some("localhost")
let port = config.port(); // Some(6379)
```
### Utilities (`utils`)
#### Validation
```rust
use veza_common::utils::validation::*;
// Email validation
assert!(validate_email("test@example.com"));
assert!(!validate_email("invalid-email"));
// Username validation
assert!(validate_username("user123"));
assert!(!validate_username("ab")); // Too short
// Password validation
assert!(validate_password("Password123"));
assert!(!validate_password("short")); // Too short
// With Result return
let result = validate_email_result("test@example.com");
assert!(result.is_ok());
```
#### Serialization
```rust
use veza_common::utils::serialization::*;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct MyStruct {
name: String,
value: i32,
}
let data = MyStruct {
name: "test".to_string(),
value: 42,
};
// Serialize to JSON
let json = to_json(&data).unwrap();
// Deserialize from JSON
let deserialized: MyStruct = from_json(&json).unwrap();
assert_eq!(data, deserialized);
// Pretty print
let pretty = to_json_pretty(&data).unwrap();
```
#### Date Utilities
```rust
use veza_common::utils::date::*;
use chrono::{DateTime, Utc, Duration};
// Format timestamp
let timestamp = 1609459200; // 2021-01-01 00:00:00 UTC
let formatted = format_timestamp(timestamp);
// Parse date
let date_str = "2021-01-01T00:00:00Z";
let dt: DateTime<Utc> = parse_date(date_str).unwrap();
// Relative time
let now = Utc::now();
let past = now - Duration::hours(2);
let relative = format_relative_time(&past, &now); // "2 hours ago"
// Current timestamp
let ts = current_timestamp();
```
#### Logging
```rust
use veza_common::utils::logging::*;
use std::collections::HashMap;
// Simple logging
log_info("api", "Service started");
log_error("api", "Connection failed", None);
// Request logging
log_request("api", "GET", "/users");
// Request with context
let mut context = HashMap::new();
context.insert("user_id".to_string(), "123".to_string());
log_request_with_context("api", "POST", "/users", &context);
// Structured logging
let entry = StructuredLogEntry::new("api", "INFO", "User created")
.with_context("user_id".to_string(), "123".to_string());
let json = entry.to_json();
```
#### General Utilities
```rust
use veza_common::utils::*;
// Generate UUID
let uuid = generate_uuid();
// Format duration
let formatted = format_duration(125); // "2:05"
// Format file size
let size = format_file_size(1024); // "1.00 KB"
```
## Exemples d'Usage Complets
### Exemple 1: Créer et valider un utilisateur
```rust
use veza_common::types::User;
use veza_common::utils::validation::validate_email_result;
fn create_user(username: String, email: String) -> Result<User, String> {
// Validate email
validate_email_result(&email)?;
// Create user
let user = User::new(1, username, email);
// Validate user data
user.validate()?;
Ok(user)
}
```
### Exemple 2: Configuration de base de données
```rust
use veza_common::config::DatabaseConfig;
use veza_common::error::CommonResult;
fn setup_database() -> CommonResult<DatabaseConfig> {
let config = DatabaseConfig::new(
std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgresql://localhost/mydb".to_string()),
20
);
// Validate configuration
config.validate()?;
Ok(config)
}
```
### Exemple 3: API Response avec pagination
```rust
use veza_common::types::{ApiResponse, PaginatedResponse};
fn get_users(page: u32, limit: u32) -> ApiResponse<PaginatedResponse<User>> {
let items = vec![/* ... */];
let total = 100;
let paginated = PaginatedResponse::new(items, total, page, limit);
ApiResponse::success(paginated)
}
```
### Exemple 4: Gestion d'erreurs
```rust
use veza_common::error::{CommonError, CommonResult};
fn process_request(data: &str) -> CommonResult<String> {
if data.is_empty() {
return Err(CommonError::ValidationError(
"Data cannot be empty".to_string()
));
}
// Process data...
Ok("processed".to_string())
}
```
## Tests
La bibliothèque inclut une infrastructure de tests complète dans `tests/common_tests.rs` avec:
- **Fixtures**: Fonctions pour créer des données de test
- **Helpers**: Fonctions utilitaires pour les tests
- **Exemples**: Tests d'intégration complets
Exécuter les tests:
```bash
cargo test
```
## Documentation API
Pour générer la documentation complète:
```bash
cargo doc --open
```
## Structure du Projet
```
veza-common/
├── src/
│ ├── lib.rs # Module principal
│ ├── types/ # Types partagés (User, Track, Playlist)
│ ├── error.rs # Gestion d'erreurs
│ ├── config/ # Configurations (Database, Redis)
│ └── utils/ # Utilitaires
│ ├── validation.rs
│ ├── serialization.rs
│ ├── date.rs
│ └── logging.rs
├── tests/
│ └── common_tests.rs # Tests d'intégration
└── Cargo.toml
```
## Licence
MIT
## Contribution
Les contributions sont les bienvenues ! Veuillez suivre les standards de code définis dans `ORIGIN_CODE_STANDARDS.md`.