use crates::chrono::{DateTime, NaiveDate, Utc};
use crates::serde::de::{DeserializeOwned, Error, Unexpected};
use crates::serde::{Deserialize, Deserializer, Serialize, Serializer};
use crates::serde_json::{self, Value};
use std::fmt::{self, Display, Formatter};
pub type QueryParamSlice<'a> = &'a [(&'a str, &'a str)];
pub type QueryParamVec<'a> = Vec<(&'a str, &'a str)>;
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct UserId(u64);
impl_id!(UserId);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UserState {
Active,
Blocked,
LdapBlocked,
}
enum_serialize!(UserState -> "user state",
Active => "active",
Blocked => "blocked",
LdapBlocked => "ldap_blocked",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UserBasic {
pub username: String,
pub name: String,
pub id: UserId,
pub state: UserState,
pub avatar_url: Option<String>,
pub web_url: String,
}
pub trait UserResult: DeserializeOwned {}
impl<T: DeserializeOwned + Into<UserBasic>> UserResult for T {}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct User {
pub username: String,
pub name: String,
pub id: UserId,
pub state: UserState,
pub avatar_url: Option<String>,
pub web_url: String,
pub created_at: Option<DateTime<Utc>>,
pub is_admin: Option<bool>,
pub highest_role: Option<AccessLevel>,
pub bio: Option<String>,
pub private_profile: Option<bool>,
pub location: Option<String>,
pub public_email: Option<String>,
pub skype: String,
pub linkedin: String,
pub twitter: String,
pub website_url: String,
pub organization: Option<String>,
}
impl From<User> for UserBasic {
fn from(user: User) -> Self {
UserBasic {
username: user.username,
name: user.name,
id: user.id,
state: user.state,
avatar_url: user.avatar_url,
web_url: user.web_url,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Identity {
pub provider: String,
pub extern_uid: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ThemeId(u64);
impl_id!(ThemeId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ColorSchemeId(u64);
impl_id!(ColorSchemeId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UserPublic {
pub username: String,
pub name: String,
pub id: UserId,
pub state: UserState,
pub avatar_url: Option<String>,
pub web_url: String,
pub created_at: Option<DateTime<Utc>>,
pub is_admin: Option<bool>,
pub highest_role: Option<AccessLevel>,
pub bio: Option<String>,
pub private_profile: Option<bool>,
pub location: Option<String>,
pub public_email: Option<String>,
pub skype: String,
pub linkedin: String,
pub twitter: String,
pub website_url: String,
pub organization: Option<String>,
pub last_sign_in_at: Option<DateTime<Utc>>,
pub last_activity_on: Option<NaiveDate>,
pub confirmed_at: Option<DateTime<Utc>>,
pub email: String,
pub theme_id: Option<ThemeId>,
pub color_scheme_id: ColorSchemeId,
pub projects_limit: u64,
pub current_sign_in_at: Option<DateTime<Utc>>,
pub identities: Vec<Identity>,
pub can_create_group: bool,
pub can_create_project: bool,
pub two_factor_enabled: bool,
pub external: bool,
}
impl From<UserPublic> for UserBasic {
fn from(user: UserPublic) -> Self {
UserBasic {
username: user.username,
name: user.name,
id: user.id,
state: user.state,
avatar_url: user.avatar_url,
web_url: user.web_url,
}
}
}
impl From<UserPublic> for User {
fn from(user: UserPublic) -> Self {
User {
username: user.username,
name: user.name,
id: user.id,
state: user.state,
avatar_url: user.avatar_url,
web_url: user.web_url,
created_at: user.created_at,
is_admin: user.is_admin,
highest_role: user.highest_role,
bio: user.bio,
private_profile: user.private_profile,
location: user.location,
public_email: user.public_email,
skype: user.skype,
linkedin: user.linkedin,
twitter: user.twitter,
website_url: user.website_url,
organization: user.organization,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct EmailId(u64);
impl_id!(EmailId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Email {
pub id: EmailId,
pub email: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct HookId(u64);
impl_id!(HookId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Hook {
pub id: HookId,
pub url: String,
pub created_at: DateTime<Utc>,
pub push_events: bool,
pub tag_push_events: bool,
pub enable_ssl_verification: bool,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProjectHook {
pub id: HookId,
pub url: String,
pub created_at: DateTime<Utc>,
pub project_id: ProjectId,
pub push_events: bool,
pub push_events_branch_filter: Option<String>,
pub tag_push_events: bool,
pub issues_events: bool,
pub confidential_issues_events: Option<bool>,
pub merge_requests_events: bool,
pub note_events: bool,
pub confidential_note_events: Option<bool>,
pub repository_update_events: bool,
pub enable_ssl_verification: bool,
pub job_events: bool,
pub pipeline_events: bool,
pub wiki_page_events: bool,
}
impl From<ProjectHook> for Hook {
fn from(hook: ProjectHook) -> Self {
Hook {
id: hook.id,
url: hook.url,
created_at: hook.created_at,
push_events: hook.push_events,
tag_push_events: hook.tag_push_events,
enable_ssl_verification: hook.enable_ssl_verification,
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct WebhookEvents {
job: bool,
issues: bool,
confidential_issues: bool,
merge_requests: bool,
note: bool,
pipeline: bool,
push: bool,
wiki_page: bool,
}
impl WebhookEvents {
pub fn new() -> Self {
WebhookEvents {
job: false,
issues: false,
confidential_issues: false,
merge_requests: false,
note: false,
pipeline: false,
push: false,
wiki_page: false,
}
}
with_event! {with_job, job}
with_event! {with_issues, issues}
with_event! {with_confidential_issues, issues}
with_event! {with_merge_requests, merge_requests}
with_event! {with_note, note}
with_event! {with_pipeline, pipeline}
with_event! {with_push, push}
with_event! {with_wiki_page, wiki_page}
get_event! {job}
get_event! {issues}
get_event! {confidential_issues}
get_event! {merge_requests}
get_event! {note}
get_event! {pipeline}
get_event! {push}
get_event! {wiki_page}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ProjectId(u64);
impl_id!(ProjectId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BasicProjectDetails {
pub id: ProjectId,
pub name: String,
pub name_with_namespace: String,
pub path: String,
pub path_with_namespace: String,
pub http_url_to_repo: String,
pub web_url: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum VisibilityLevel {
Public,
Internal,
Private,
}
enum_serialize!(VisibilityLevel -> "visibility level",
Public => "public",
Internal => "internal",
Private => "private",
);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum FeatureVisibilityLevel {
Disabled,
Private,
Enabled,
Public,
}
enum_serialize!(FeatureVisibilityLevel -> "feature visibility level",
Disabled => "disabled",
Private => "private",
Enabled => "enabled",
Public => "public",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SharedGroup {
pub group_id: GroupId,
pub group_name: String,
pub group_access_level: u64,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct MemberAccess {
pub access_level: u64,
pub notification_level: Option<u64>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct Permissions {
pub project_access: Option<MemberAccess>,
pub group_access: Option<MemberAccess>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProjectNamespaceAvatar {
pub url: Option<String>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
struct ProjectLinks {
#[serde(rename = "self")]
self_: String,
issues: Option<String>,
merge_requests: Option<String>,
repo_branches: String,
labels: String,
events: String,
members: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Project {
pub id: ProjectId,
pub description: Option<String>,
pub default_branch: Option<String>,
pub tag_list: Vec<String>,
pub archived: bool,
pub empty_repo: bool,
pub visibility: VisibilityLevel,
pub ssh_url_to_repo: String,
pub http_url_to_repo: String,
pub web_url: String,
pub readme_url: Option<String>,
pub owner: Option<UserBasic>,
pub name: String,
pub name_with_namespace: String,
pub path: String,
pub path_with_namespace: String,
pub container_registry_enabled: Option<bool>,
pub created_at: DateTime<Utc>,
pub last_activity_at: DateTime<Utc>,
pub shared_runners_enabled: bool,
pub lfs_enabled: bool,
pub creator_id: UserId,
pub namespace: Namespace,
pub forked_from_project: Option<BasicProjectDetails>,
pub avatar_url: Option<String>,
pub ci_config_path: Option<String>,
pub import_error: Option<String>,
pub star_count: u64,
pub forks_count: u64,
pub open_issues_count: Option<u64>,
pub runners_token: Option<String>,
pub public_jobs: bool,
pub shared_with_groups: Vec<SharedGroup>,
pub only_allow_merge_if_pipeline_succeeds: Option<bool>,
pub only_allow_merge_if_all_discussions_are_resolved: Option<bool>,
pub printing_merge_request_link_enabled: Option<bool>,
pub request_access_enabled: bool,
pub resolve_outdated_diff_discussions: Option<bool>,
pub jobs_enabled: bool,
pub issues_enabled: bool,
pub merge_requests_enabled: bool,
pub snippets_enabled: bool,
pub wiki_enabled: bool,
pub builds_access_level: FeatureVisibilityLevel,
pub issues_access_level: FeatureVisibilityLevel,
pub merge_requests_access_level: FeatureVisibilityLevel,
pub repository_access_level: FeatureVisibilityLevel,
pub snippets_access_level: FeatureVisibilityLevel,
pub wiki_access_level: FeatureVisibilityLevel,
pub merge_method: Option<String>,
pub statistics: Option<ProjectStatistics>,
pub permissions: Option<Permissions>,
_links: Option<ProjectLinks>,
}
#[cfg(test)]
impl Project {
pub fn has_links(&self) -> bool {
self._links.is_some()
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct ProjectStatistics {
pub commit_count: u64,
pub storage_size: u64,
pub repository_size: u64,
pub lfs_objects_size: u64,
pub job_artifacts_size: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum AccessLevel {
Anonymous,
Guest,
Reporter,
Developer,
Maintainer,
Owner,
}
impl From<AccessLevel> for u64 {
fn from(access: AccessLevel) -> Self {
match access {
AccessLevel::Anonymous => 0,
AccessLevel::Guest => 10,
AccessLevel::Reporter => 20,
AccessLevel::Developer => 30,
AccessLevel::Maintainer => 40,
AccessLevel::Owner => 50,
}
}
}
impl From<u64> for AccessLevel {
fn from(access: u64) -> Self {
if access >= 50 {
AccessLevel::Owner
} else if access >= 40 {
AccessLevel::Maintainer
} else if access >= 30 {
AccessLevel::Developer
} else if access >= 20 {
AccessLevel::Reporter
} else if access >= 10 {
AccessLevel::Guest
} else {
AccessLevel::Anonymous
}
}
}
impl Display for AccessLevel {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", Into::<u64>::into(self.clone()))
}
}
impl Serialize for AccessLevel {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
u64::from(*self).serialize(serializer)
}
}
impl<'de> Deserialize<'de> for AccessLevel {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(<u64 as Deserialize>::deserialize(deserializer)?.into())
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Member {
pub username: String,
pub name: String,
pub id: UserId,
pub state: UserState,
pub avatar_url: Option<String>,
pub web_url: String,
pub access_level: u64,
pub expires_at: Option<NaiveDate>,
}
impl From<Member> for UserBasic {
fn from(member: Member) -> Self {
UserBasic {
username: member.username,
name: member.name,
id: member.id,
state: member.state,
avatar_url: member.avatar_url,
web_url: member.web_url,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AccessRequester {
pub username: String,
pub name: String,
pub id: UserId,
pub state: UserState,
pub avatar_url: Option<String>,
pub web_url: String,
pub requested_at: DateTime<Utc>,
}
impl From<AccessRequester> for UserBasic {
fn from(member: AccessRequester) -> Self {
UserBasic {
username: member.username,
name: member.name,
id: member.id,
state: member.state,
avatar_url: member.avatar_url,
web_url: member.web_url,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct GroupId(u64);
impl_id!(GroupId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Group {
pub id: GroupId,
pub name: String,
pub path: String,
pub description: Option<String>,
pub visibility: VisibilityLevel,
pub lfs_enabled: bool,
pub avatar_url: Option<String>,
pub web_url: String,
pub request_access_enabled: bool,
pub full_name: String,
pub full_path: String,
pub parent_id: Option<GroupId>,
pub statistics: Option<GroupStatistics>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct GroupStatistics {
pub storage_size: u64,
pub repository_size: u64,
pub lfs_objects_size: u64,
pub job_artifacts_size: u64,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GroupDetail {
pub id: GroupId,
pub name: String,
pub path: String,
pub description: Option<String>,
pub visibility: VisibilityLevel,
pub lfs_enabled: bool,
pub avatar_url: Option<String>,
pub web_url: String,
pub projects: Vec<Project>,
pub shared_projects: Vec<Project>,
pub request_access_enabled: bool,
pub full_name: String,
pub full_path: String,
pub parent_id: Option<GroupId>,
pub statistics: Option<GroupStatistics>,
}
impl From<GroupDetail> for Group {
fn from(detail: GroupDetail) -> Self {
Group {
id: detail.id,
name: detail.name,
path: detail.path,
description: detail.description,
visibility: detail.visibility,
lfs_enabled: detail.lfs_enabled,
avatar_url: detail.avatar_url,
web_url: detail.web_url,
request_access_enabled: detail.request_access_enabled,
full_name: detail.full_name,
full_path: detail.full_path,
parent_id: detail.parent_id,
statistics: detail.statistics,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RepoBranch {
pub name: String,
pub commit: Option<RepoCommit>,
pub merged: Option<bool>,
pub protected: Option<bool>,
pub developers_can_push: Option<bool>,
pub developers_can_merge: Option<bool>,
pub can_push: Option<bool>,
pub default: Option<bool>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct ObjectId(String);
impl ObjectId {
pub fn new<O: ToString>(oid: O) -> Self {
ObjectId(oid.to_string())
}
pub fn value(&self) -> &String {
&self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectType {
Tree,
Blob,
}
enum_serialize!(ObjectType -> "object type",
Tree => "tree",
Blob => "blob",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RepoTreeObject {
pub id: ObjectId,
pub name: String,
#[serde(rename = "type")]
pub type_: ObjectType,
pub path: String,
pub mode: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RepoCommit {
pub id: ObjectId,
pub short_id: ObjectId,
pub title: String,
pub parent_ids: Vec<ObjectId>,
pub author_name: String,
pub author_email: String,
pub authored_date: DateTime<Utc>,
pub committer_name: String,
pub committer_email: String,
pub committed_date: DateTime<Utc>,
pub created_at: DateTime<Utc>,
pub message: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct RepoCommitStats {
pub additions: u64,
pub deletions: u64,
pub total: u64,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RepoCommitDetail {
pub id: ObjectId,
pub short_id: ObjectId,
pub title: String,
pub parent_ids: Vec<ObjectId>,
pub author_name: String,
pub author_email: String,
pub authored_date: DateTime<Utc>,
pub committer_name: String,
pub committer_email: String,
pub committed_date: DateTime<Utc>,
pub created_at: DateTime<Utc>,
pub message: String,
pub stats: Option<RepoCommitStats>,
pub last_pipeline: Option<PipelineBasic>,
pub project_id: ProjectId,
status: Value,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct SnippetId(u64);
impl_id!(SnippetId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProjectSnippet {
pub id: SnippetId,
pub title: String,
pub file_name: String,
pub author: UserBasic,
pub updated_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
pub web_url: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RepoDiff {
pub old_path: String,
pub new_path: String,
pub a_mode: String,
pub b_mode: String,
pub diff: String,
pub new_file: bool,
pub renamed_file: bool,
pub deleted_file: bool,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct DiffRefs {
pub base_sha: Option<ObjectId>,
pub head_sha: Option<ObjectId>,
pub start_sha: Option<ObjectId>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MilestoneId(u64);
impl_id!(MilestoneId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MilestoneInternalId(u64);
impl_id!(MilestoneInternalId);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MilestoneState {
Active,
Closed,
}
enum_serialize!(MilestoneState -> "milestone type",
Active => "active",
Closed => "closed",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Milestone {
pub id: MilestoneId,
pub iid: MilestoneInternalId,
pub project_id: Option<ProjectId>,
pub group_id: Option<GroupId>,
pub title: String,
pub description: Option<String>,
pub state: MilestoneState,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub due_date: Option<NaiveDate>,
pub start_date: Option<NaiveDate>,
}
impl Milestone {
pub fn new(project_id: ProjectId, title: String) -> Milestone {
Milestone {
id: MilestoneId::new(0),
iid: MilestoneInternalId::new(0),
project_id: Some(project_id),
group_id: None,
title: title,
description: None,
state: MilestoneState::Active,
created_at: DateTime::from(Utc::now()),
updated_at: DateTime::from(Utc::now()),
due_date: None,
start_date: None,
}
}
pub fn with_description(mut self, description: String) -> Milestone {
self.description = Some(description);
self
}
pub fn with_due_date(mut self, due_date: NaiveDate) -> Milestone {
self.due_date = Some(due_date);
self
}
pub fn with_start_date(mut self, start_date: NaiveDate) -> Milestone {
self.start_date = Some(start_date);
self
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct LabelId(u64);
impl_id!(LabelId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct LabelColor(String);
impl LabelColor {
pub fn from_rgb(r: u8, g: u8, b: u8) -> LabelColor {
LabelColor(format!("#{:02X}{:02X}{:02X}", r, g, b))
}
pub fn from_str(stdcolor: &str) -> LabelColor {
let hex = match stdcolor {
"white" => "FFFFFF",
"silver" => "C0C0C0",
"gray" => "808080",
"black" => "000000",
"red" => "FF0000",
"maroon" => "800000",
"yellow" => "FFFF00",
"olive" => "808000",
"lime" => "00FF00",
"green" => "008000",
"aqua" => "00FFFF",
"teal" => "008080",
"blue" => "0000FF",
"navy" => "000080",
"fuchsia" => "FF00FF",
"purple" => "800080",
_ => "808080",
};
LabelColor(format!("#{}", hex))
}
pub fn value(self) -> String {
self.0
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Label {
pub id: LabelId,
pub name: String,
pub color: LabelColor,
pub description: Option<String>,
pub open_issues_count: u64,
pub closed_issues_count: u64,
pub open_merge_requests_count: u64,
pub subscribed: bool,
pub priority: Option<u64>,
}
impl Label {
pub fn new(name: String, color: LabelColor) -> Label {
Label {
id: LabelId::new(0),
name: name,
color: color,
description: None,
open_issues_count: 0,
closed_issues_count: 0,
open_merge_requests_count: 0,
subscribed: false,
priority: None,
}
}
pub fn with_description(mut self, description: String) -> Label {
self.description = Some(description);
self
}
pub fn with_priority(mut self, priority: u64) -> Label {
self.priority = Some(priority);
self
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct IssueId(u64);
impl_id!(IssueId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct IssueInternalId(u64);
impl_id!(IssueInternalId);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IssueState {
Opened,
Closed,
Reopened,
}
enum_serialize!(IssueState -> "issue type",
Opened => "opened",
Closed => "closed",
Reopened => "reopened",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
struct IssueLinks {
#[serde(rename = "self")]
self_: String,
notes: String,
award_emoji: String,
project: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Issue {
pub id: IssueId,
pub iid: IssueInternalId,
pub project_id: ProjectId,
pub title: String,
pub description: Option<String>,
pub state: IssueState,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub closed_at: Option<DateTime<Utc>>,
pub closed_by: Option<UserBasic>,
pub labels: Vec<String>,
pub milestone: Option<Milestone>,
pub author: UserBasic,
pub assignee: Option<UserBasic>,
pub assignees: Option<Vec<UserBasic>>,
pub subscribed: Option<bool>,
pub time_stats: IssuableTimeStats,
pub user_notes_count: u64,
pub merge_requests_count: u64,
pub upvotes: u64,
pub downvotes: u64,
pub due_date: Option<NaiveDate>,
pub has_tasks: Option<bool>,
pub confidential: bool,
pub discussion_locked: Option<bool>,
pub web_url: String,
_links: Option<IssueLinks>,
}
impl Issue {
pub fn new(project_id: ProjectId, title: String, author: UserBasic) -> Issue {
Issue {
id: IssueId::new(0),
iid: IssueInternalId::new(0),
project_id: project_id,
title: title,
description: None,
state: IssueState::Opened,
created_at: DateTime::from(Utc::now()),
updated_at: DateTime::from(Utc::now()),
closed_at: None,
closed_by: None,
labels: Vec::new(),
milestone: None,
author: author,
assignee: None,
assignees: None,
subscribed: None,
time_stats: IssuableTimeStats {
time_estimate: 0,
total_time_spent: 0,
human_time_estimate: None,
human_total_time_spent: None,
},
user_notes_count: 0,
merge_requests_count: 0,
upvotes: 0,
downvotes: 0,
due_date: None,
has_tasks: None,
confidential: false,
discussion_locked: None,
web_url: "".to_string(),
_links: None,
}
}
pub fn with_iid(mut self, iid: IssueInternalId) -> Issue {
self.iid = iid;
self
}
pub fn with_description(mut self, description: String) -> Issue {
self.description = Some(description);
self
}
pub fn with_confidential(mut self, confidential: bool) -> Issue {
self.confidential = confidential;
self
}
pub fn with_assignees(mut self, assignees: Vec<UserBasic>) -> Issue {
self.assignees = Some(assignees);
self
}
pub fn with_milestone(mut self, milestone: Milestone) -> Issue {
self.milestone = Some(milestone);
self
}
pub fn with_labels(mut self, labels: Vec<String>) -> Issue {
self.labels = labels;
self
}
pub fn with_created_at(mut self, created_at: DateTime<Utc>) -> Issue {
self.created_at = created_at;
self
}
pub fn with_due_date(mut self, due_date: NaiveDate) -> Issue {
self.due_date = Some(due_date);
self
}
pub fn has_links(&self) -> bool {
self._links.is_some()
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct IssuableTimeStats {
pub time_estimate: u64,
pub total_time_spent: u64,
pub human_time_estimate: Option<String>,
pub human_total_time_spent: Option<String>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExternalIssueId(u64);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ExternalIssue {
pub id: ExternalIssueId,
pub title: String,
}
#[derive(Debug, Clone)]
pub enum IssueReference {
Internal(Issue),
External(ExternalIssue),
}
impl Serialize for IssueReference {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match *self {
IssueReference::Internal(ref issue) => issue.serialize(serializer),
IssueReference::External(ref issue) => issue.serialize(serializer),
}
}
}
impl<'de> Deserialize<'de> for IssueReference {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let val = <Value as Deserialize>::deserialize(deserializer)?;
serde_json::from_value::<Issue>(val.clone())
.map(IssueReference::Internal)
.or_else(|_| serde_json::from_value::<ExternalIssue>(val).map(IssueReference::External))
.map_err(|err| D::Error::custom(format!("invalid issue reference: {:?}", err)))
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MergeRequestId(u64);
impl_id!(MergeRequestId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MergeRequestInternalId(u64);
impl_id!(MergeRequestInternalId);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MergeStatus {
Unchecked,
CanBeMerged,
CannotBeMerged,
CannotBeMergedRecheck,
}
enum_serialize!(MergeStatus -> "merge status",
Unchecked => "unchecked",
CanBeMerged => "can_be_merged",
CannotBeMerged => "cannot_be_merged",
CannotBeMergedRecheck => "cannot_be_merged_recheck",
);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MergeRequestState {
Opened,
Closed,
Reopened,
Merged,
Locked,
}
enum_serialize!(MergeRequestState -> "merge request state",
Opened => "opened",
Closed => "closed",
Reopened => "reopened",
Merged => "merged",
Locked => "locked",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MergeRequestUser {
pub can_merge: bool,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MergeRequest {
pub id: MergeRequestId,
pub iid: MergeRequestInternalId,
pub project_id: ProjectId,
pub title: String,
pub description: Option<String>,
pub state: MergeRequestState,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub merged_at: Option<DateTime<Utc>>,
pub closed_at: Option<DateTime<Utc>>,
pub merged_by: Option<UserBasic>,
pub closed_by: Option<UserBasic>,
pub target_branch: String,
pub source_branch: String,
pub upvotes: u64,
pub downvotes: u64,
pub author: UserBasic,
pub assignee: Option<UserBasic>,
pub assignees: Option<Vec<UserBasic>>,
pub source_project_id: ProjectId,
pub target_project_id: ProjectId,
pub labels: Vec<String>,
pub work_in_progress: bool,
pub allow_collaboration: Option<bool>,
pub allow_maintainer_to_push: Option<bool>,
pub milestone: Option<Milestone>,
pub squash: bool,
pub merge_when_pipeline_succeeds: bool,
pub merge_status: MergeStatus,
pub sha: Option<ObjectId>,
pub diff_refs: Option<DiffRefs>,
pub merge_error: Option<String>,
pub rebase_in_progress: Option<bool>,
pub merge_commit_sha: Option<ObjectId>,
pub subscribed: Option<bool>,
pub time_stats: IssuableTimeStats,
pub changes_count: Option<String>,
pub user_notes_count: u64,
pub discussion_locked: Option<bool>,
pub should_remove_source_branch: Option<bool>,
pub force_remove_source_branch: Option<bool>,
pub user: Option<MergeRequestUser>,
pub web_url: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MergeRequestChanges {
pub id: MergeRequestId,
pub iid: MergeRequestInternalId,
pub project_id: ProjectId,
pub title: String,
pub description: Option<String>,
pub state: MergeRequestState,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub merged_at: Option<DateTime<Utc>>,
pub closed_at: Option<DateTime<Utc>>,
pub merged_by: Option<UserBasic>,
pub closed_by: Option<UserBasic>,
pub target_branch: String,
pub source_branch: String,
pub upvotes: u64,
pub downvotes: u64,
pub author: UserBasic,
pub assignee: Option<UserBasic>,
pub assignees: Option<Vec<UserBasic>>,
pub source_project_id: ProjectId,
pub target_project_id: ProjectId,
pub labels: Vec<String>,
pub work_in_progress: bool,
pub allow_collaboration: Option<bool>,
pub allow_maintainer_to_push: Option<bool>,
pub milestone: Option<Milestone>,
pub squash: bool,
pub merge_when_pipeline_succeeds: bool,
pub merge_status: MergeStatus,
pub sha: Option<ObjectId>,
pub diff_refs: Option<DiffRefs>,
pub merge_error: Option<String>,
pub rebase_in_progress: Option<bool>,
pub merge_commit_sha: Option<ObjectId>,
pub subscribed: Option<bool>,
pub time_stats: IssuableTimeStats,
pub changes_count: Option<String>,
pub user_notes_count: u64,
pub discussion_locked: Option<bool>,
pub should_remove_source_branch: Option<bool>,
pub force_remove_source_branch: Option<bool>,
pub user: MergeRequestUser,
pub web_url: String,
pub changes: Vec<RepoDiff>,
}
impl From<MergeRequestChanges> for MergeRequest {
fn from(mr: MergeRequestChanges) -> Self {
MergeRequest {
id: mr.id,
iid: mr.iid,
project_id: mr.project_id,
title: mr.title,
description: mr.description,
state: mr.state,
created_at: mr.created_at,
updated_at: mr.updated_at,
merged_at: mr.merged_at,
closed_at: mr.closed_at,
merged_by: mr.merged_by,
closed_by: mr.closed_by,
target_branch: mr.target_branch,
source_branch: mr.source_branch,
upvotes: mr.upvotes,
downvotes: mr.downvotes,
author: mr.author,
assignee: mr.assignee,
assignees: mr.assignees,
source_project_id: mr.source_project_id,
target_project_id: mr.target_project_id,
labels: mr.labels,
work_in_progress: mr.work_in_progress,
allow_collaboration: mr.allow_collaboration,
allow_maintainer_to_push: mr.allow_maintainer_to_push,
milestone: mr.milestone,
squash: mr.squash,
merge_when_pipeline_succeeds: mr.merge_when_pipeline_succeeds,
merge_status: mr.merge_status,
sha: mr.sha,
diff_refs: mr.diff_refs,
merge_error: mr.merge_error,
rebase_in_progress: mr.rebase_in_progress,
merge_commit_sha: mr.merge_commit_sha,
subscribed: mr.subscribed,
time_stats: mr.time_stats,
changes_count: mr.changes_count,
user_notes_count: mr.user_notes_count,
discussion_locked: mr.discussion_locked,
should_remove_source_branch: mr.should_remove_source_branch,
force_remove_source_branch: mr.force_remove_source_branch,
user: Some(mr.user),
web_url: mr.web_url,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct SshKeyId(u64);
impl_id!(SshKeyId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SshKey {
pub id: SshKeyId,
pub title: String,
pub key: String,
pub created_at: DateTime<Utc>,
pub can_push: bool,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SshKeyWithUser {
pub id: SshKeyId,
pub title: String,
pub key: String,
pub created_at: DateTime<Utc>,
pub user: UserPublic,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NoteType {
Commit,
Issue,
MergeRequest,
Snippet,
}
enum_serialize!(NoteType -> "note type",
Commit => "Commit",
Issue => "Issue",
MergeRequest => "MergeRequest",
Snippet => "Snippet",
);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NoteableId {
Commit(ObjectId),
Issue(IssueId),
MergeRequest(MergeRequestId),
Snippet(SnippetId),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NoteableInternalId {
Issue(IssueInternalId),
MergeRequest(MergeRequestInternalId),
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoteId(u64);
impl_id!(NoteId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Note {
pub id: NoteId,
pub body: String,
pub attachment: Option<String>,
pub author: UserBasic,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub resolvable: bool,
pub resolved: Option<bool>,
pub resolved_by: Option<UserBasic>,
pub system: bool,
noteable_id: Value,
noteable_iid: Option<Value>,
pub noteable_type: NoteType,
}
impl Note {
pub fn noteable_id(&self) -> Option<NoteableId> {
match self.noteable_type {
NoteType::Commit => {
self.noteable_id
.as_str()
.map(|id| NoteableId::Commit(ObjectId::new(id)))
},
NoteType::Issue => {
self.noteable_id
.as_u64()
.map(|id| NoteableId::Issue(IssueId::new(id)))
},
NoteType::MergeRequest => {
self.noteable_id
.as_u64()
.map(|id| NoteableId::MergeRequest(MergeRequestId::new(id)))
},
NoteType::Snippet => {
self.noteable_id
.as_u64()
.map(|id| NoteableId::Snippet(SnippetId::new(id)))
},
}
}
pub fn noteable_iid(&self) -> Option<NoteableInternalId> {
match self.noteable_type {
NoteType::Commit => None,
NoteType::Issue => {
self.noteable_iid
.as_ref()
.and_then(|value| value.as_u64())
.map(|id| NoteableInternalId::Issue(IssueInternalId::new(id)))
},
NoteType::MergeRequest => {
self.noteable_iid
.as_ref()
.and_then(|value| value.as_u64())
.map(|id| NoteableInternalId::MergeRequest(MergeRequestInternalId::new(id)))
},
NoteType::Snippet => None,
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct AwardId(u64);
impl_id!(AwardId);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AwardableId {
Issue(IssueId),
MergeRequest(MergeRequestId),
Snippet(SnippetId),
Note(NoteId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AwardableType {
Issue,
MergeRequest,
Snippet,
Note,
}
enum_serialize!(AwardableType -> "awardable type",
Issue => "Issue",
MergeRequest => "MergeRequest",
Snippet => "Snippet",
Note => "Note",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AwardEmoji {
pub id: AwardId,
pub name: String,
pub user: UserBasic,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
awardable_id: u64,
pub awardable_type: AwardableType,
}
impl AwardEmoji {
pub fn awardable_id(&self) -> AwardableId {
match self.awardable_type {
AwardableType::Issue => AwardableId::Issue(IssueId::new(self.awardable_id)),
AwardableType::MergeRequest => {
AwardableId::MergeRequest(MergeRequestId::new(self.awardable_id))
},
AwardableType::Snippet => AwardableId::Snippet(SnippetId::new(self.awardable_id)),
AwardableType::Note => AwardableId::Note(NoteId::new(self.awardable_id)),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LineType {
New,
Old,
}
enum_serialize!(LineType -> "line type",
New => "new",
Old => "old",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CommitNote {
pub note: String,
pub path: Option<String>,
pub line: Option<u64>,
pub line_type: Option<LineType>,
pub author: UserBasic,
pub created_at: DateTime<Utc>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct CommitStatusId(u64);
impl_id!(CommitStatusId);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StatusState {
Created,
Pending,
Running,
Success,
Failed,
Canceled,
Skipped,
Manual,
}
enum_serialize!(StatusState -> "status state",
Created => "created",
Pending => "pending",
Running => "running",
Success => "success",
Failed => "failed",
Canceled => "canceled",
Skipped => "skipped",
Manual => "manual",
);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CommitStatus {
pub id: CommitStatusId,
pub sha: ObjectId,
#[serde(rename = "ref")]
pub ref_: Option<String>,
pub status: StatusState,
pub name: String,
pub target_url: Option<String>,
pub description: Option<String>,
pub created_at: DateTime<Utc>,
pub started_at: Option<DateTime<Utc>>,
pub finished_at: Option<DateTime<Utc>>,
pub allow_failure: bool,
pub coverage: Option<u64>,
pub author: UserBasic,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EventTargetType {
Commit,
Issue,
MergeRequest,
Snippet,
ProjectSnippet,
}
enum_serialize!(EventTargetType -> "event target type",
Commit => "commit",
Issue => "issue",
MergeRequest => "merge_request",
Snippet => "snippet",
ProjectSnippet => "project_snippet",
);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventTargetId {
Commit(ObjectId),
Issue(IssueId),
MergeRequest(MergeRequestId),
Snippet(SnippetId),
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Event {
pub title: Option<String>,
pub project_id: ProjectId,
pub action_name: String,
target_id: Value,
pub target_type: EventTargetType,
pub author_id: UserId,
pub data: Option<Value>,
pub target_title: String,
pub created_at: DateTime<Utc>,
pub note: Option<Note>,
pub author: Option<UserBasic>,
pub author_username: Option<String>,
}
impl Event {
pub fn target_id(&self) -> Option<EventTargetId> {
match self.target_type {
EventTargetType::Commit => {
self.target_id
.as_str()
.map(|id| EventTargetId::Commit(ObjectId(id.to_string())))
},
EventTargetType::Issue => {
self.target_id
.as_u64()
.map(|id| EventTargetId::Issue(IssueId(id)))
},
EventTargetType::MergeRequest => {
self.target_id
.as_u64()
.map(|id| EventTargetId::MergeRequest(MergeRequestId(id)))
},
EventTargetType::Snippet => {
self.target_id
.as_u64()
.map(|id| EventTargetId::Snippet(SnippetId(id)))
},
EventTargetType::ProjectSnippet => {
self.target_id
.as_u64()
.map(|id| EventTargetId::Snippet(SnippetId(id)))
},
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NamespaceKind {
User,
Group,
}
enum_serialize!(NamespaceKind -> "namespace kind",
User => "user",
Group => "group",
);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NamespaceId {
User(UserId),
Group(GroupId),
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Namespace {
id: u64,
pub path: String,
pub name: String,
pub kind: NamespaceKind,
pub full_path: String,
pub members_count_with_descendants: Option<u64>,
pub avatar_url: Option<String>,
pub web_url: String,
}
impl Namespace {
pub fn id(&self) -> NamespaceId {
match self.kind {
NamespaceKind::User => NamespaceId::User(UserId(self.id)),
NamespaceKind::Group => NamespaceId::Group(GroupId(self.id)),
}
}
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct RunnerId(u64);
impl_id!(RunnerId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Runner {
pub id: RunnerId,
pub description: Option<String>,
pub active: bool,
pub is_shared: bool,
pub name: Option<String>,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JobArtifactFile {
pub filename: String,
pub size: usize,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct JobId(u64);
impl_id!(JobId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Job {
pub id: JobId,
pub status: StatusState,
pub stage: String,
pub name: String,
#[serde(rename = "ref")]
pub ref_: Option<String>,
pub tag: bool,
pub coverage: Option<f32>,
pub created_at: DateTime<Utc>,
pub started_at: Option<DateTime<Utc>>,
pub finished_at: Option<DateTime<Utc>>,
pub user: Option<User>,
pub artifacts_file: Option<JobArtifactFile>,
pub commit: RepoCommit,
pub runner: Option<Runner>,
pub pipeline: PipelineBasic,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct PipelineId(u64);
impl_id!(PipelineId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PipelineBasic {
pub id: PipelineId,
#[serde(rename = "ref")]
pub ref_: Option<String>,
pub sha: ObjectId,
pub status: StatusState,
pub web_url: String,
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct LabelEventId(u64);
impl_id!(LabelEventId);
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ResourceLabelEvent {
pub id: LabelEventId,
pub user: UserBasic,
pub created_at: DateTime<Utc>,
resource_id: u64,
resource_type: String,
pub label: Option<EventLabel>,
pub action: String
}
impl ResourceLabelEvent {
pub fn event_target(&self) -> Option<ResourceLabelEventTarget> {
match self.resource_type.as_ref() {
"MergeRequest" => Some(ResourceLabelEventTarget::MergeRequest(MergeRequestId::new(self.resource_id))),
"Issue" => Some(ResourceLabelEventTarget::Issue(IssueId::new(self.resource_id))),
_ => None
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ResourceLabelEventTarget {
Issue(IssueId),
MergeRequest(MergeRequestId),
}
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EventLabel {
pub id: LabelId,
pub name: String,
pub color: LabelColor,
pub description: Option<String>,
}