use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use crate::{constants::REQUIRES_DLC_TAG, search::Searchable};
#[typeshare]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct RemoteMod {
pub download_url: String,
pub download_count: u32,
pub version: String,
pub name: String,
pub unique_name: String,
pub description: String,
pub readme: Option<ModReadMe>,
pub slug: String,
required: Option<bool>,
pub repo: String,
pub author: String,
pub author_display: Option<String>,
pub parent: Option<String>,
pub prerelease: Option<ModPrerelease>,
pub thumbnail: ModThumbnail,
alpha: Option<bool>,
pub tags: Option<Vec<String>>,
}
impl RemoteMod {
pub fn get_author(&self) -> &String {
self.author_display.as_ref().unwrap_or(&self.author)
}
pub fn requires_dlc(&self) -> bool {
self.tags
.as_ref()
.map(|tags| tags.contains(&REQUIRES_DLC_TAG.to_string()))
.unwrap_or(false)
}
#[cfg(test)]
pub fn get_test(num: u8) -> Self {
serde_json::from_str(
&include_str!("../../test_files/test_remote_mod.json")
.replace("$num$", &num.to_string()),
)
.unwrap()
}
}
impl Searchable for RemoteMod {
fn get_values(&self) -> Vec<String> {
let tags_iter = self
.tags
.as_ref()
.map(|v| v.iter().cloned())
.unwrap_or_default();
Vec::from_iter(
[
self.name.clone(),
self.unique_name.clone(),
self.get_author().clone(),
self.description.clone(),
]
.into_iter()
.chain(tags_iter),
)
}
fn break_tie(&self, other: &Self) -> std::cmp::Ordering {
self.download_count.cmp(&other.download_count).reverse()
}
}
#[typeshare]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ModPrerelease {
pub download_url: String,
pub version: String,
}
#[typeshare]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ModReadMe {
pub html_url: String,
pub download_url: String,
}
#[typeshare]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ModThumbnail {
pub main: Option<String>,
pub open_graph: Option<String>,
}
impl ModThumbnail {
pub const BASE_URL: &'static str = "https://ow-mods.github.io/ow-mod-db/thumbnails/";
pub fn get_main_url(&self) -> Option<String> {
self.main
.as_ref()
.map(|main| format!("{}{}", Self::BASE_URL, main))
}
pub fn get_static_url(&self) -> Option<String> {
self.open_graph
.as_ref()
.or(self.main.as_ref())
.map(|open_graph| format!("{}{}", Self::BASE_URL, open_graph))
}
}