// rust/01-cicd-configuration.rs/*CI/CD pipeline configuration and best practices*/usestd::collections::HashMap;useserde::{Deserialize,Serialize};usestd::process::Command;/// CI/CD pipeline configuration.#[derive(Debug, Clone, Serialize, Deserialize)]pubstructPipelineConfig{pubname:String,pubversion:String,pubstages:Vec<PipelineStage>,pubvariables:HashMap<String,String>,pubartifacts:Vec<String>,pubnotifications:Vec<NotificationConfig>,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructPipelineStage{pubname:String,pubcommands:Vec<String>,pubdependencies:Vec<String>,pubtimeout:Option<u64>,pubretry_count:Option<u32>,pubparallel:bool,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructNotificationConfig{pubevent:String,pubwebhook_url:String,pubtemplate:String,}implPipelineConfig{pubfnnew(name:String,version:String)->Self{Self{name,version,stages:Vec::new(),variables:HashMap::new(),artifacts:Vec::new(),notifications:Vec::new(),}}/// Add a stage to the pipeline.pubfnadd_stage(&mutself,stage:PipelineStage){self.stages.push(stage);}/// Set a pipeline variable.pubfnset_variable(&mutself,key:String,value:String){self.variables.insert(key,value);}/// Add an artifact to the pipeline.pubfnadd_artifact(&mutself,artifact:String){self.artifacts.push(artifact);}/// Add a notification configuration.pubfnadd_notification(&mutself,notification:NotificationConfig){self.notifications.push(notification);}}/// Pipeline executor.pubstructPipelineExecutor{config:PipelineConfig,results:HashMap<String,StageResult>,}#[derive(Debug, Clone)]pubstructStageResult{pubstage_name:String,pubstatus:StageStatus,pubduration:std::time::Duration,puboutput:String,puberror:Option<String>,}#[derive(Debug, Clone, PartialEq)]pubenumStageStatus{Success,Failure,Skipped,Running,}implPipelineExecutor{pubfnnew(config:PipelineConfig)->Self{Self{config,results:HashMap::new(),}}/// Execute the pipeline.pubasyncfnexecute(&mutself)->Result<(),String>{println!("Starting pipeline: {}",self.config.name);forstagein&self.config.stages{println!("Executing stage: {}",stage.name);letstart_time=std::time::Instant::now();letresult=self.execute_stage(stage).await;letduration=start_time.elapsed();letstage_result=StageResult{stage_name:stage.name.clone(),status:ifresult.is_ok(){StageStatus::Success}else{StageStatus::Failure},duration,output:result.as_ref().unwrap_or(&String::new()).clone(),error:result.err(),};self.results.insert(stage.name.clone(),stage_result);ifresult.is_err(){println!("Stage {} failed: {:?}",stage.name,result.err());returnErr(format!("Stage {} failed",stage.name));}}println!("Pipeline completed successfully");Ok(())}/// Execute a single stage.asyncfnexecute_stage(&self,stage:&PipelineStage)->Result<String,String>{letmutoutput=String::new();forcommandin&stage.commands{letresult=self.execute_command(command).await?;output.push_str(&result);output.push('\n');}Ok(output)}/// Execute a single command.asyncfnexecute_command(&self,command:&str)->Result<String,String>{letoutput=Command::new("sh").arg("-c").arg(command).output().map_err(|e|format!("Failed to execute command: {}",e))?;if!output.status.success(){returnErr(format!("Command failed: {}",String::from_utf8_lossy(&output.stderr)));}Ok(String::from_utf8_lossy(&output.stdout).to_string())}/// Get stage results.pubfnget_results(&self)->&HashMap<String,StageResult>{&self.results}/// Get pipeline summary.pubfnget_summary(&self)->String{lettotal_stages=self.results.len();letsuccessful_stages=self.results.values().filter(|r|r.status==StageStatus::Success).count();letfailed_stages=self.results.values().filter(|r|r.status==StageStatus::Failure).count();format!("Pipeline Summary: {} total stages, {} successful, {} failed",total_stages,successful_stages,failed_stages)}}/// Pipeline builder for creating complex pipelines.pubstructPipelineBuilder{config:PipelineConfig,}implPipelineBuilder{pubfnnew(name:String,version:String)->Self{Self{config:PipelineConfig::new(name,version),}}/// Add a test stage.pubfnadd_test_stage(mutself)->Self{letstage=PipelineStage{name:"test".to_string(),commands:vec!["cargo test --verbose".to_string(),"cargo clippy -- -D warnings".to_string(),"cargo fmt --all -- --check".to_string(),],dependencies:Vec::new(),timeout:Some(300),retry_count:Some(2),parallel:false,};self.config.add_stage(stage);self}/// Add a security stage.pubfnadd_security_stage(mutself)->Self{letstage=PipelineStage{name:"security".to_string(),commands:vec!["cargo audit".to_string(),"cargo deny check".to_string(),"cargo outdated --exit-code 1".to_string(),],dependencies:vec!["test".to_string()],timeout:Some(180),retry_count:Some(1),parallel:false,};self.config.add_stage(stage);self}/// Add a build stage.pubfnadd_build_stage(mutself)->Self{letstage=PipelineStage{name:"build".to_string(),commands:vec!["cargo build --release".to_string(),"cargo build --release --target x86_64-unknown-linux-musl".to_string(),],dependencies:vec!["test".to_string(),"security".to_string()],timeout:Some(600),retry_count:Some(1),parallel:false,};self.config.add_stage(stage);self}/// Add a deploy stage.pubfnadd_deploy_stage(mutself)->Self{letstage=PipelineStage{name:"deploy".to_string(),commands:vec!["echo 'Deploying to production'".to_string(),"docker build -t rust-app:latest .".to_string(),"docker push rust-app:latest".to_string(),],dependencies:vec!["build".to_string()],timeout:Some(900),retry_count:Some(1),parallel:false,};self.config.add_stage(stage);self}/// Set pipeline variables.pubfnset_variables(mutself,variables:HashMap<String,String>)->Self{for(key,value)invariables{self.config.set_variable(key,value);}self}/// Add artifacts.pubfnadd_artifacts(mutself,artifacts:Vec<String>)->Self{forartifactinartifacts{self.config.add_artifact(artifact);}self}/// Build the pipeline configuration.pubfnbuild(self)->PipelineConfig{self.config}}#[cfg(test)]modtests{usesuper::*;#[test]fntest_pipeline_config(){letmutconfig=PipelineConfig::new("test-pipeline".to_string(),"1.0.0".to_string());letstage=PipelineStage{name:"test".to_string(),commands:vec!["cargo test".to_string()],dependencies:Vec::new(),timeout:Some(300),retry_count:Some(2),parallel:false,};config.add_stage(stage);assert_eq!(config.stages.len(),1);}#[test]fntest_pipeline_builder(){letconfig=PipelineBuilder::new("test-pipeline".to_string(),"1.0.0".to_string()).add_test_stage().add_security_stage().add_build_stage().add_deploy_stage().build();assert_eq!(config.stages.len(),4);assert_eq!(config.name,"test-pipeline");}}
// rust/02-quality-gates.rs/*Quality gates and best practices*/usestd::collections::HashMap;useserde::{Deserialize,Serialize};/// Quality gate configuration.#[derive(Debug, Clone, Serialize, Deserialize)]pubstructQualityGate{pubname:String,pubmetrics:Vec<QualityMetric>,pubthresholds:HashMap<String,f64>,pubrequired:bool,}#[derive(Debug, Clone, Serialize, Deserialize)]pubstructQualityMetric{pubname:String,pubvalue:f64,pubthreshold:f64,puboperator:ComparisonOperator,}#[derive(Debug, Clone, Serialize, Deserialize)]pubenumComparisonOperator{LessThan,LessThanOrEqual,GreaterThan,GreaterThanOrEqual,Equal,NotEqual,}implQualityGate{pubfnnew(name:String)->Self{Self{name,metrics:Vec::new(),thresholds:HashMap::new(),required:true,}}/// Add a quality metric.pubfnadd_metric(&mutself,metric:QualityMetric){self.metrics.push(metric);}/// Set a threshold for a metric.pubfnset_threshold(&mutself,metric_name:String,threshold:f64){self.thresholds.insert(metric_name,threshold);}/// Check if the quality gate passes.pubfncheck(&self)->QualityGateResult{letmutresults=Vec::new();letmutpassed=true;formetricin&self.metrics{letresult=self.check_metric(metric);results.push(result.clone());if!result.passed{passed=false;}}QualityGateResult{gate_name:self.name.clone(),passed,results,}}/// Check a single metric.fncheck_metric(&self,metric:&QualityMetric)->MetricResult{letpassed=matchmetric.operator{ComparisonOperator::LessThan=>metric.value<metric.threshold,ComparisonOperator::LessThanOrEqual=>metric.value<=metric.threshold,ComparisonOperator::GreaterThan=>metric.value>metric.threshold,ComparisonOperator::GreaterThanOrEqual=>metric.value>=metric.threshold,ComparisonOperator::Equal=>metric.value==metric.threshold,ComparisonOperator::NotEqual=>metric.value!=metric.threshold,};MetricResult{metric_name:metric.name.clone(),value:metric.value,threshold:metric.threshold,passed,}}}#[derive(Debug, Clone)]pubstructQualityGateResult{pubgate_name:String,pubpassed:bool,pubresults:Vec<MetricResult>,}#[derive(Debug, Clone)]pubstructMetricResult{pubmetric_name:String,pubvalue:f64,pubthreshold:f64,pubpassed:bool,}/// Quality gate manager.pubstructQualityGateManager{gates:Vec<QualityGate>,results:HashMap<String,QualityGateResult>,}implQualityGateManager{pubfnnew()->Self{Self{gates:Vec::new(),results:HashMap::new(),}}/// Add a quality gate.pubfnadd_gate(&mutself,gate:QualityGate){self.gates.push(gate);}/// Check all quality gates.pubfncheck_all(&mutself)->HashMap<String,QualityGateResult>{letmutresults=HashMap::new();forgatein&self.gates{letresult=gate.check();results.insert(gate.name.clone(),result.clone());}self.results=results.clone();results}/// Get quality gate results.pubfnget_results(&self)->&HashMap<String,QualityGateResult>{&self.results}/// Check if all quality gates pass.pubfnall_passed(&self)->bool{self.results.values().all(|result|result.passed)}/// Get quality gate summary.pubfnget_summary(&self)->String{lettotal_gates=self.results.len();letpassed_gates=self.results.values().filter(|result|result.passed).count();letfailed_gates=total_gates-passed_gates;format!("Quality Gates: {} total, {} passed, {} failed",total_gates,passed_gates,failed_gates)}}/// Code quality analyzer.pubstructCodeQualityAnalyzer{metrics:HashMap<String,f64>,}implCodeQualityAnalyzer{pubfnnew()->Self{Self{metrics:HashMap::new(),}}/// Analyze code quality.pubfnanalyze(&mutself)->Result<(),String>{// Analyze test coverageself.analyze_test_coverage()?;// Analyze code complexityself.analyze_complexity()?;// Analyze maintainabilityself.analyze_maintainability()?;// Analyze securityself.analyze_security()?;Ok(())}/// Analyze test coverage.fnanalyze_test_coverage(&mutself)->Result<(),String>{// In a real implementation, you would run cargo tarpaulin// or similar tool to get test coverageself.metrics.insert("test_coverage".to_string(),85.0);Ok(())}/// Analyze code complexity.fnanalyze_complexity(&mutself)->Result<(),String>{// In a real implementation, you would run cargo clippy// or similar tool to get complexity metricsself.metrics.insert("cyclomatic_complexity".to_string(),5.2);Ok(())}/// Analyze maintainability.fnanalyze_maintainability(&mutself)->Result<(),String>{// In a real implementation, you would run various tools// to get maintainability metricsself.metrics.insert("maintainability_index".to_string(),75.0);Ok(())}/// Analyze security.fnanalyze_security(&mutself)->Result<(),String>{// In a real implementation, you would run cargo audit// or similar tool to get security metricsself.metrics.insert("security_score".to_string(),90.0);Ok(())}/// Get quality metrics.pubfnget_metrics(&self)->&HashMap<String,f64>{&self.metrics}}#[cfg(test)]modtests{usesuper::*;#[test]fntest_quality_gate(){letmutgate=QualityGate::new("test-gate".to_string());letmetric=QualityMetric{name:"test_coverage".to_string(),value:85.0,threshold:80.0,operator:ComparisonOperator::GreaterThanOrEqual,};gate.add_metric(metric);letresult=gate.check();assert!(result.passed);}#[test]fntest_quality_gate_manager(){letmutmanager=QualityGateManager::new();letmutgate=QualityGate::new("test-gate".to_string());letmetric=QualityMetric{name:"test_coverage".to_string(),value:85.0,threshold:80.0,operator:ComparisonOperator::GreaterThanOrEqual,};gate.add_metric(metric);manager.add_gate(gate);letresults=manager.check_all();assert_eq!(results.len(),1);assert!(manager.all_passed());}#[test]fntest_code_quality_analyzer(){letmutanalyzer=CodeQualityAnalyzer::new();analyzer.analyze().unwrap();letmetrics=analyzer.get_metrics();assert!(metrics.contains_key("test_coverage"));assert!(metrics.contains_key("cyclomatic_complexity"));}}