- apps/web: test updates (Vitest/setup), playbackAnalyticsService, TrackGrid, serviceErrorHandler - veza-common: logging, metrics, traits, validation, random - veza-stream-server: audio pipeline, codecs, cache, monitoring, routes - apps/web/dist_verification: refresh build assets (content-hashed filenames) Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| AUDIT_REPORT.md | ||
| Cargo.toml | ||
| README.md | ||
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:
[dependencies]
veza-common = { path = "../veza-common" }
Modules
Types (types)
Types de données partagés pour tous les services.
User
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
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
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
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.
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
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
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
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
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
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
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
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
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
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
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
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:
cargo test
Documentation API
Pour générer la documentation complète:
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.