mockforge-core 0.3.116

Shared logic for MockForge - routing, validation, latency, proxy
Documentation
//! PR template generation
//!
//! This module provides templates for generating PR titles and descriptions.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Context for PR template generation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PRTemplateContext {
    /// Endpoint affected
    pub endpoint: String,
    /// HTTP method
    pub method: String,
    /// Number of breaking changes
    pub breaking_changes: u32,
    /// Number of non-breaking changes
    pub non_breaking_changes: u32,
    /// List of affected files
    pub affected_files: Vec<String>,
    /// Change summary
    pub change_summary: String,
    /// Whether this is a breaking change
    pub is_breaking: bool,
    /// Additional context
    pub metadata: HashMap<String, serde_json::Value>,
}

/// PR template generator
#[derive(Debug, Clone)]
pub struct PRTemplate;

impl PRTemplate {
    /// Generate PR title
    pub fn generate_title(context: &PRTemplateContext) -> String {
        if context.is_breaking {
            format!("🚨 [BREAKING] Update contract for {} {}", context.method, context.endpoint)
        } else {
            format!("📝 Update contract for {} {}", context.method, context.endpoint)
        }
    }

    /// Generate PR body
    pub fn generate_body(context: &PRTemplateContext) -> String {
        let mut body = String::new();

        // Header
        body.push_str("## Contract Update\n\n");
        body.push_str(&format!(
            "This PR updates the contract for `{} {}`\n\n",
            context.method, context.endpoint
        ));

        // Breaking changes warning
        if context.is_breaking {
            body.push_str("### ⚠️ Breaking Changes Detected\n\n");
            body.push_str(&format!(
                "This update includes **{} breaking change(s)**. Please review carefully.\n\n",
                context.breaking_changes
            ));
        }

        // Change summary
        body.push_str("### Change Summary\n\n");
        body.push_str(&context.change_summary);
        body.push_str("\n\n");

        // Statistics
        body.push_str("### Statistics\n\n");
        body.push_str(&format!("- Breaking changes: {}\n", context.breaking_changes));
        body.push_str(&format!("- Non-breaking changes: {}\n", context.non_breaking_changes));
        body.push_str(&format!(
            "- Total changes: {}\n\n",
            context.breaking_changes + context.non_breaking_changes
        ));

        // Affected files
        if !context.affected_files.is_empty() {
            body.push_str("### Affected Files\n\n");
            for file in &context.affected_files {
                body.push_str(&format!("- `{}`\n", file));
            }
            body.push('\n');
        }

        // Testing instructions
        body.push_str("### Testing Instructions\n\n");
        body.push_str("Please verify that:\n");
        body.push_str("- [ ] All affected endpoints still work correctly\n");
        if context.is_breaking {
            body.push_str("- [ ] Breaking changes are documented\n");
            body.push_str("- [ ] Consumers have been notified\n");
        }
        body.push_str("- [ ] Mock fixtures are updated\n");
        body.push_str("- [ ] Generated clients are updated\n");
        body.push_str("- [ ] Example tests pass\n\n");

        // Footer
        body.push_str("---\n");
        body.push_str("*This PR was automatically generated by MockForge*\n");

        body
    }
}