feat(types): Add GitLab Resource Event serde types with deserialization tests

Adds six new types for deserializing responses from GitLab's three
Resource Events API endpoints (state, label, milestone):

- GitLabStateEvent: State transitions with optional user, source_commit,
  and source_merge_request reference
- GitLabLabelEvent: Label add/remove events with nested GitLabLabelRef
- GitLabMilestoneEvent: Milestone assignment changes with nested
  GitLabMilestoneRef
- GitLabMergeRequestRef: Lightweight MR reference (iid, title, web_url)
- GitLabLabelRef: Label metadata (id, name, color, description)
- GitLabMilestoneRef: Milestone metadata (id, iid, title)

All types derive Deserialize + Serialize and use Option<T> for nullable
fields (user, source_commit, color, description) to match GitLab's API
contract where these fields may be null.

Includes 8 new test cases covering:
- State events with/without user, with/without source_merge_request
- Label events for add and remove actions, including null color handling
- Milestone event deserialization
- Standalone ref type deserialization (MR, label, milestone)

Uses r##"..."## raw string delimiters where JSON contains hex color
codes (#FF0000) that would conflict with r#"..."# delimiters.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-03 12:06:56 -05:00
parent ce5cd9c95d
commit 92ff255909
3 changed files with 277 additions and 4 deletions

View File

@@ -10,6 +10,7 @@ pub use transformers::{
transform_discussion, transform_issue, transform_notes,
};
pub use types::{
GitLabAuthor, GitLabDiscussion, GitLabIssue, GitLabNote, GitLabNotePosition, GitLabProject,
GitLabUser, GitLabVersion,
GitLabAuthor, GitLabDiscussion, GitLabIssue, GitLabLabelEvent, GitLabLabelRef,
GitLabMergeRequestRef, GitLabMilestoneEvent, GitLabMilestoneRef, GitLabNote,
GitLabNotePosition, GitLabProject, GitLabStateEvent, GitLabUser, GitLabVersion,
};

View File

@@ -182,6 +182,70 @@ impl GitLabLineRange {
}
}
// === Resource Event types (Phase B - Gate 1) ===
/// Reference to an MR in state event's source_merge_request field.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabMergeRequestRef {
pub iid: i64,
pub title: Option<String>,
pub web_url: Option<String>,
}
/// Reference to a label in label event's label field.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabLabelRef {
pub id: i64,
pub name: String,
pub color: Option<String>,
pub description: Option<String>,
}
/// Reference to a milestone in milestone event's milestone field.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabMilestoneRef {
pub id: i64,
pub iid: i64,
pub title: String,
}
/// State change event from the Resource State Events API.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabStateEvent {
pub id: i64,
pub user: Option<GitLabAuthor>,
pub created_at: String,
pub resource_type: String,
pub resource_id: i64,
pub state: String,
pub source_commit: Option<String>,
pub source_merge_request: Option<GitLabMergeRequestRef>,
}
/// Label change event from the Resource Label Events API.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabLabelEvent {
pub id: i64,
pub user: Option<GitLabAuthor>,
pub created_at: String,
pub resource_type: String,
pub resource_id: i64,
pub label: GitLabLabelRef,
pub action: String,
}
/// Milestone change event from the Resource Milestone Events API.
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabMilestoneEvent {
pub id: i64,
pub user: Option<GitLabAuthor>,
pub created_at: String,
pub resource_type: String,
pub resource_id: i64,
pub milestone: GitLabMilestoneRef,
pub action: String,
}
// === Checkpoint 2: Merge Request types ===
/// GitLab MR references (short and full reference strings).