n5i 0.8.0

Common components for n5i
Documentation
// SPDX-FileCopyrightText: 2024-2026 The n5i Project
//
// SPDX-License-Identifier: AGPL-3.0-or-later

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,
    // Developer name -> their website
    pub developers: BTreeMap<String, String>,
    pub license: String,
}

#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct AppStore {
    pub id: uuid::Uuid,
    #[serde(flatten)]
    pub metadata: StoreMetadata,
    #[serde(default)]
    pub r#type: StoreType,
    pub src: HashMap<String, String>,

    // Data specific to the app store type
    pub provider_data: serde_json::Value,
}

#[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]
    // Rename for backwards compatibility
    #[serde(rename = "Nirvati")]
    Git,
    Plugin,
}

#[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(StoreType::Git),
            -1 => Ok(StoreType::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 {}