hgame 0.26.4

CG production management structs, e.g. of assets, personnels, progress, etc.
Documentation
mod offline;
#[cfg(feature = "image_processing")]
mod thumb;
mod web_link;

use super::*;
pub use offline::Offline;
#[cfg(feature = "image_processing")]
pub use thumb::*;
pub use web_link::*;

#[cfg(all(any(feature = "mongo", feature = "kitsu"), feature = "gui"))]
use hconf::Umbrella;
use mkentity::ProjectSource;

const MAX_PROJECT_NAME_LENGTH: usize = 10;
const MANUAL_PROJECT_SRC_HINT: &str = "▓ Offline/Manual";
#[cfg(feature = "mongo")]
const MONGO_PROJECT_SRC_HINT: &str = "🏁 MongoDB";
#[cfg(feature = "kitsu")]
const KITSU_PROJECT_SRC_HINT: &str = "🐘 Kitsu (experimental)";

// ----------------------------------------------------------------------------
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "persistence", derive(Serialize, Deserialize))]
/// A production project.
pub enum Project {
    Manual(String),

    #[cfg(feature = "mongo")]
    Mongo(MongoProject),

    #[cfg(feature = "kitsu")]
    Kitsu(KitsuProject),
}

impl Project {
    pub fn source(&self) -> ProjectSource {
        match &self {
            Self::Manual(_) => ProjectSource::Offline,

            #[cfg(feature = "mongo")]
            Self::Mongo(_) => ProjectSource::Mongo,

            #[cfg(feature = "kitsu")]
            Self::Kitsu(_) => ProjectSource::Zou,
        }
    }

    pub fn null(typ: &ProjectSource) -> Self {
        match typ {
            ProjectSource::Offline => Self::Manual(String::new()),

            #[cfg(feature = "mongo")]
            ProjectSource::Mongo => Self::Mongo(MongoProject::null()),

            #[cfg(feature = "kitsu")]
            ProjectSource::Zou => Self::Kitsu(KitsuProject::null()),

            #[allow(unreachable_patterns)]
            _ => unreachable!(),
        }
    }

    #[cfg(feature = "mongo")]
    pub fn mongo_from_name(name: &str) -> Self {
        Self::Mongo(MongoProject::from_name(name))
    }

    #[cfg(feature = "kitsu")]
    pub fn kitsu_from_name(name: &str) -> Self {
        Self::Kitsu(KitsuProject::from_name(name))
    }

    pub fn from_name(name: &str, typ: &ProjectSource) -> Self {
        match typ {
            ProjectSource::Offline => Self::Manual(name.to_owned()),

            #[cfg(feature = "mongo")]
            ProjectSource::Mongo => Self::mongo_from_name(name),

            #[cfg(feature = "kitsu")]
            ProjectSource::Zou => Self::kitsu_from_name(name),

            #[allow(unreachable_patterns)]
            _ => unreachable!(),
        }
    }
    /// Uses the inner's name attribute
    pub fn as_str(&self) -> &str {
        match self {
            Self::Manual(inner) => &inner,

            #[cfg(feature = "mongo")]
            Self::Mongo(inner) => &inner.name,

            #[cfg(feature = "kitsu")]
            Self::Kitsu(inner) => &inner.name,
        }
    }
    /// Uses the inner's name attribute
    pub fn to_string(&self) -> String {
        self.as_str().to_owned()
    }
    pub fn hint_db_source(&self) -> &'static str {
        match self {
            Self::Manual(_) => MANUAL_PROJECT_SRC_HINT,

            #[cfg(feature = "mongo")]
            Self::Mongo(_) => MONGO_PROJECT_SRC_HINT,

            #[cfg(feature = "kitsu")]
            Self::Kitsu(_) => KITSU_PROJECT_SRC_HINT,
        }
    }
}

impl fmt::Display for Project {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[cfg(feature = "gui")]
impl From<&Project> for egui::WidgetText {
    fn from(project: &Project) -> Self {
        egui::WidgetText::RichText(egui::RichText::new(project.as_str()))
    }
}

// ----------------------------------------------------------------------------
#[cfg(feature = "mongo")]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "persistence", derive(Serialize, Deserialize))]
pub struct MongoProject {
    name: String,
}

#[cfg(feature = "mongo")]
impl MongoProject {
    fn from_name(name: &str) -> Self {
        Self {
            name: name.to_owned(),
        }
    }
    fn null() -> Self {
        Self {
            name: String::new(),
        }
    }
}

// -------------------------------------------------------------------------------
#[cfg(feature = "kitsu")]
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize, Hash)]
/// External API: DO NOT change field names.
pub struct KitsuProject {
    id: String,
    name: String,
    production_type: String,
}

#[cfg(feature = "kitsu")]
impl KitsuProject {
    fn from_name(name: &str) -> Self {
        Self {
            name: name.to_owned(),
            ..Self::default()
        }
    }
    fn null() -> Self {
        Self::default()
    }
}

// -------------------------------------------------------------------------------

#[cfg(all(any(feature = "mongo", feature = "kitsu"), feature = "gui"))]
/// UI to edit an [`Umbrella`] override.
pub fn pp_umbrella_ui(um: &mut Umbrella, label: &str, needs_save: &mut bool, ui: &mut egui::Ui) {
    ui.horizontal(|ui| {
        if ui.checkbox(&mut um.enabled, label).clicked() {
            *needs_save = true;
        };
        if um.enabled {
            if ui
                .add(egui::TextEdit::singleline(&mut um.name).text_color(Color32::YELLOW))
                .changed()
            {
                *needs_save = true;
            };
        };
    });
}