use crate::utils::MultiLanguageItem;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt::{self, Debug};
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
#[cfg_attr(feature = "graphql", derive(async_graphql::SimpleObject))]
pub struct StoreMetadata {
pub name: MultiLanguageItem,
pub tagline: MultiLanguageItem,
pub description: MultiLanguageItem,
pub icon: String,
pub developers: BTreeMap<String, String>,
pub license: String,
}
#[derive(Debug, Deserialize, Clone, Default)]
pub struct LegacyAppStore {
pub id: uuid::Uuid,
#[serde(flatten)]
pub metadata: StoreMetadata,
#[serde(default)]
pub r#type: StoreType,
pub src: HashMap<String, String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct AppStore {
pub id: uuid::Uuid,
#[serde(flatten)]
pub metadata: StoreMetadata,
pub provider_id: String,
pub format_id: String,
pub src: HashMap<String, String>,
}
#[derive(Debug, Deserialize, Clone)]
#[serde(untagged)]
pub enum OnDiskAppStore {
Legacy(LegacyAppStore),
Current(AppStore),
}
impl TryFrom<LegacyAppStore> for AppStore {
type Error = anyhow::Error;
fn try_from(legacy: LegacyAppStore) -> Result<Self, Self::Error> {
Ok(Self {
id: legacy.id,
metadata: legacy.metadata,
provider_id: match legacy.r#type {
StoreType::Git => "git".to_string(),
StoreType::Plugin => "plugin".to_string(),
StoreType::Http => "http".to_string(),
},
format_id: match legacy.r#type {
StoreType::Git => "git".to_string(),
StoreType::Plugin => legacy
.src
.get("plugin_id")
.cloned()
.ok_or_else(|| anyhow::anyhow!("Missing plugin_id for plugin store"))?,
StoreType::Http => "http".to_string(),
},
src: legacy.src,
})
}
}
impl TryFrom<OnDiskAppStore> for AppStore {
type Error = anyhow::Error;
fn try_from(on_disk: OnDiskAppStore) -> Result<Self, Self::Error> {
match on_disk {
OnDiskAppStore::Legacy(legacy) => legacy.try_into(),
OnDiskAppStore::Current(current) => Ok(current),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AppUpdateInfo {
pub id: String,
pub current_version: semver::Version,
pub new_version: semver::Version,
pub release_notes: BTreeMap<String, MultiLanguageItem>,
pub current_permissions: HashSet<String>,
pub new_permissions: HashSet<String>,
}
pub type StoresYml = Vec<AppStore>;
#[derive(Debug, Serialize, Deserialize, Clone, Default, Eq, PartialEq)]
pub enum StoreType {
#[default]
#[serde(rename = "Nirvati")]
Git,
Plugin,
Http,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct InvalidEnumValue(pub i32);
impl TryFrom<i32> for StoreType {
type Error = InvalidEnumValue;
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::Git),
-1 => Ok(Self::Plugin),
unknown => Err(InvalidEnumValue(unknown)),
}
}
}
impl fmt::Display for InvalidEnumValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Invalid enum value {}", self.0)
}
}
impl std::error::Error for InvalidEnumValue {}