2024-10-18 16:07:35 -07:00

233 lines
6.1 KiB
Rust

use chrono::{DateTime, Utc};
use labrinth::{
auth::AuthProvider,
models::{
images::ImageId,
notifications::NotificationId,
organizations::OrganizationId,
projects::{
Dependency, GalleryItem, License, ModeratorMessage,
MonetizationStatus, ProjectId, ProjectStatus, VersionFile,
VersionId, VersionStatus, VersionType,
},
reports::ReportId,
teams::{ProjectPermissions, TeamId},
threads::{ThreadId, ThreadMessageId},
users::{Badges, Role, User, UserId, UserPayoutData},
},
};
use rust_decimal::Decimal;
use serde::Deserialize;
// Fields shared by every version of the API.
// No struct in here should have ANY field that
// is not present in *every* version of the API.
// Exceptions are fields that *should* be changing across the API, and older versions
// should be unsupported on API version increase- for example, payouts related financial fields.
// These are used for common tests- tests that can be used on both V2 AND v3 of the API and have the same results.
// Any test that requires version-specific fields should have its own test that is not done for each version,
// as the environment generator for both uses common fields.
#[derive(Deserialize)]
pub struct CommonProject {
// For example, for CommonProject, we do not include:
// - game_versions (v2 only)
// - loader_fields (v3 only)
// - etc.
// For any tests that require those fields, we make a separate test with separate API functions tht do not use Common models.
pub id: ProjectId,
pub slug: Option<String>,
pub organization: Option<OrganizationId>,
pub published: DateTime<Utc>,
pub updated: DateTime<Utc>,
pub approved: Option<DateTime<Utc>>,
pub queued: Option<DateTime<Utc>>,
pub status: ProjectStatus,
pub requested_status: Option<ProjectStatus>,
pub moderator_message: Option<ModeratorMessage>,
pub license: License,
pub downloads: u32,
pub followers: u32,
pub categories: Vec<String>,
pub additional_categories: Vec<String>,
pub loaders: Vec<String>,
pub versions: Vec<VersionId>,
pub icon_url: Option<String>,
pub gallery: Vec<GalleryItem>,
pub color: Option<u32>,
pub thread_id: ThreadId,
pub monetization_status: MonetizationStatus,
}
#[derive(Deserialize, Clone)]
pub struct CommonVersion {
pub id: VersionId,
pub loaders: Vec<String>,
pub project_id: ProjectId,
pub author_id: UserId,
pub featured: bool,
pub name: String,
pub version_number: String,
pub changelog: String,
pub date_published: DateTime<Utc>,
pub downloads: u32,
pub version_type: VersionType,
pub status: VersionStatus,
pub requested_status: Option<VersionStatus>,
pub files: Vec<VersionFile>,
pub dependencies: Vec<Dependency>,
}
#[derive(Deserialize)]
pub struct CommonLoaderData {
pub icon: String,
pub name: String,
pub supported_project_types: Vec<String>,
}
#[derive(Deserialize)]
pub struct CommonCategoryData {
pub icon: String,
pub name: String,
pub project_type: String,
pub header: String,
}
/// A member of a team
#[derive(Deserialize)]
pub struct CommonTeamMember {
pub team_id: TeamId,
pub user: User,
pub role: String,
pub permissions: Option<ProjectPermissions>,
pub accepted: bool,
pub payouts_split: Option<Decimal>,
pub ordering: i64,
}
#[derive(Deserialize)]
pub struct CommonNotification {
pub id: NotificationId,
pub user_id: UserId,
pub read: bool,
pub created: DateTime<Utc>,
// Body is absent as one of the variants differs
pub text: String,
pub link: String,
pub actions: Vec<CommonNotificationAction>,
}
#[derive(Deserialize)]
pub struct CommonNotificationAction {
pub action_route: (String, String),
}
#[derive(Deserialize, Clone)]
#[serde(rename_all = "kebab-case")]
pub enum CommonItemType {
Project,
Version,
User,
Unknown,
}
impl CommonItemType {
pub fn as_str(&self) -> &'static str {
match self {
CommonItemType::Project => "project",
CommonItemType::Version => "version",
CommonItemType::User => "user",
CommonItemType::Unknown => "unknown",
}
}
}
#[derive(Deserialize)]
pub struct CommonReport {
pub id: ReportId,
pub report_type: String,
pub item_id: String,
pub item_type: CommonItemType,
pub reporter: UserId,
pub body: String,
pub created: DateTime<Utc>,
pub closed: bool,
pub thread_id: ThreadId,
}
#[derive(Deserialize)]
pub enum LegacyItemType {
Project,
Version,
User,
Unknown,
}
#[derive(Deserialize)]
pub struct CommonThread {
pub id: ThreadId,
#[serde(rename = "type")]
pub type_: CommonThreadType,
pub project_id: Option<ProjectId>,
pub report_id: Option<ReportId>,
pub messages: Vec<CommonThreadMessage>,
pub members: Vec<User>,
}
#[derive(Deserialize)]
pub struct CommonThreadMessage {
pub id: ThreadMessageId,
pub author_id: Option<UserId>,
pub body: CommonMessageBody,
pub created: DateTime<Utc>,
}
#[derive(Deserialize)]
pub enum CommonMessageBody {
Text {
body: String,
#[serde(default)]
private: bool,
replying_to: Option<ThreadMessageId>,
#[serde(default)]
associated_images: Vec<ImageId>,
},
StatusChange {
new_status: ProjectStatus,
old_status: ProjectStatus,
},
ThreadClosure,
ThreadReopen,
Deleted,
}
#[derive(Deserialize)]
pub enum CommonThreadType {
Report,
Project,
DirectMessage,
}
#[derive(Deserialize)]
pub struct CommonUser {
pub id: UserId,
pub username: String,
pub name: Option<String>,
pub avatar_url: Option<String>,
pub bio: Option<String>,
pub created: DateTime<Utc>,
pub role: Role,
pub badges: Badges,
pub auth_providers: Option<Vec<AuthProvider>>,
pub email: Option<String>,
pub email_verified: Option<bool>,
pub has_password: Option<bool>,
pub has_totp: Option<bool>,
pub payout_data: Option<UserPayoutData>,
pub github_id: Option<u64>,
}