use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PRTemplateContext {
pub endpoint: String,
pub method: String,
pub breaking_changes: u32,
pub non_breaking_changes: u32,
pub affected_files: Vec<String>,
pub change_summary: String,
pub is_breaking: bool,
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct PRTemplate;
impl PRTemplate {
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)
}
}
pub fn generate_body(context: &PRTemplateContext) -> String {
let mut body = String::new();
body.push_str("## Contract Update\n\n");
body.push_str(&format!(
"This PR updates the contract for `{} {}`\n\n",
context.method, context.endpoint
));
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
));
}
body.push_str("### Change Summary\n\n");
body.push_str(&context.change_summary);
body.push_str("\n\n");
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
));
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');
}
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");
body.push_str("---\n");
body.push_str("*This PR was automatically generated by MockForge*\n");
body
}
}