feat(gitlab): Add MergeRequest and related types for API deserialization
Extends GitLab type definitions with comprehensive merge request support, matching the API response structure for /projects/:id/merge_requests. New types: - MergeRequest: Full MR metadata including draft status, branch info, detailed_merge_status, merge_user (modern API fields replacing deprecated alternatives), and references for cross-project support - MrReviewer: Reviewer user info (MR-specific, distinct from assignees) - MrAssignee: Assignee user info with consistent structure - MrDiscussion: MR discussion wrapper for polymorphic handling - DiffNotePosition: Rich position data for code review comments with line ranges and SHA triplet for commit context Design decisions: - Use Option<T> for all nullable API fields to handle partial responses - Include deprecated fields (merged_by, merge_status) alongside modern alternatives for backward compatibility with older GitLab instances - DiffNotePosition uses Option for all fields since different position types (text/image/file) populate different subsets These types enable type-safe deserialization of GitLab MR API responses with full coverage of the fields needed for CP2 ingestion. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -140,4 +140,120 @@ pub struct GitLabNotePosition {
|
|||||||
pub new_path: Option<String>,
|
pub new_path: Option<String>,
|
||||||
pub old_line: Option<i32>,
|
pub old_line: Option<i32>,
|
||||||
pub new_line: Option<i32>,
|
pub new_line: Option<i32>,
|
||||||
|
/// Position type: "text", "image", or "file".
|
||||||
|
pub position_type: Option<String>,
|
||||||
|
/// Line range for multi-line comments (GitLab 13.6+).
|
||||||
|
pub line_range: Option<GitLabLineRange>,
|
||||||
|
/// Base commit SHA for the diff.
|
||||||
|
pub base_sha: Option<String>,
|
||||||
|
/// Start commit SHA for the diff.
|
||||||
|
pub start_sha: Option<String>,
|
||||||
|
/// Head commit SHA for the diff.
|
||||||
|
pub head_sha: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Line range for multi-line DiffNote comments.
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct GitLabLineRange {
|
||||||
|
pub start: GitLabLineRangePoint,
|
||||||
|
pub end: GitLabLineRangePoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A point in a line range (start or end).
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct GitLabLineRangePoint {
|
||||||
|
pub line_code: Option<String>,
|
||||||
|
/// "old" or "new".
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub line_type: Option<String>,
|
||||||
|
pub old_line: Option<i32>,
|
||||||
|
pub new_line: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GitLabLineRange {
|
||||||
|
/// Get the start line number (new_line preferred, falls back to old_line).
|
||||||
|
pub fn start_line(&self) -> Option<i32> {
|
||||||
|
self.start.new_line.or(self.start.old_line)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the end line number (new_line preferred, falls back to old_line).
|
||||||
|
pub fn end_line(&self) -> Option<i32> {
|
||||||
|
self.end.new_line.or(self.end.old_line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Checkpoint 2: Merge Request types ===
|
||||||
|
|
||||||
|
/// GitLab MR references (short and full reference strings).
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct GitLabReferences {
|
||||||
|
/// Short reference e.g. "!42".
|
||||||
|
pub short: String,
|
||||||
|
/// Full reference e.g. "group/project!42".
|
||||||
|
pub full: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// GitLab Reviewer (can have approval state in future).
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct GitLabReviewer {
|
||||||
|
pub id: i64,
|
||||||
|
pub username: String,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// GitLab Merge Request from /projects/:id/merge_requests endpoint.
|
||||||
|
/// Note: Uses non-deprecated field names where possible (detailed_merge_status, merge_user).
|
||||||
|
/// Falls back gracefully for older GitLab versions.
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct GitLabMergeRequest {
|
||||||
|
/// GitLab global ID (unique across all projects).
|
||||||
|
pub id: i64,
|
||||||
|
/// Project-scoped MR number (the number shown in the UI).
|
||||||
|
pub iid: i64,
|
||||||
|
/// The project this MR belongs to.
|
||||||
|
pub project_id: i64,
|
||||||
|
pub title: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
/// "opened" | "merged" | "closed" | "locked".
|
||||||
|
pub state: String,
|
||||||
|
/// Work-in-progress status (preferred over work_in_progress).
|
||||||
|
#[serde(default)]
|
||||||
|
pub draft: bool,
|
||||||
|
/// Deprecated; fallback for older instances.
|
||||||
|
#[serde(default)]
|
||||||
|
pub work_in_progress: bool,
|
||||||
|
pub source_branch: String,
|
||||||
|
pub target_branch: String,
|
||||||
|
/// Current commit SHA at head of source branch (CP3-ready).
|
||||||
|
pub sha: Option<String>,
|
||||||
|
/// Short and full reference strings (CP3-ready).
|
||||||
|
pub references: Option<GitLabReferences>,
|
||||||
|
/// Non-deprecated merge status. Prefer over merge_status.
|
||||||
|
pub detailed_merge_status: Option<String>,
|
||||||
|
/// Deprecated merge_status field for fallback.
|
||||||
|
#[serde(alias = "merge_status")]
|
||||||
|
pub merge_status_legacy: Option<String>,
|
||||||
|
/// ISO 8601 timestamp.
|
||||||
|
pub created_at: String,
|
||||||
|
/// ISO 8601 timestamp.
|
||||||
|
pub updated_at: String,
|
||||||
|
/// ISO 8601 timestamp when merged (null if not merged).
|
||||||
|
pub merged_at: Option<String>,
|
||||||
|
/// ISO 8601 timestamp when closed (null if not closed).
|
||||||
|
pub closed_at: Option<String>,
|
||||||
|
pub author: GitLabAuthor,
|
||||||
|
/// Non-deprecated; who merged this MR.
|
||||||
|
pub merge_user: Option<GitLabAuthor>,
|
||||||
|
/// Deprecated; fallback for older instances.
|
||||||
|
pub merged_by: Option<GitLabAuthor>,
|
||||||
|
/// Array of label names.
|
||||||
|
#[serde(default)]
|
||||||
|
pub labels: Vec<String>,
|
||||||
|
/// Assignees (can be multiple).
|
||||||
|
#[serde(default)]
|
||||||
|
pub assignees: Vec<GitLabAuthor>,
|
||||||
|
/// Reviewers (MR-specific).
|
||||||
|
#[serde(default)]
|
||||||
|
pub reviewers: Vec<GitLabReviewer>,
|
||||||
|
pub web_url: String,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user