df_st_legends_plus 0.3.0-development-2

Legends_plus.xml for the DF Storyteller project.
Documentation
use df_st_core::{Filler, HasUnknown};
use df_st_derive::{HasUnknown, HashAndPartialEqById};
use indexmap::IndexMap;
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;

#[derive(Serialize, Deserialize, Clone, Debug, HasUnknown, HashAndPartialEqById)]
pub struct WrittenContent {
    pub id: i32,
    pub title: Option<String>,
    pub page_start: Option<i32>,
    pub page_end: Option<i32>,
    #[serde(alias = "type")]
    pub type_: Option<String>,
    pub style: Option<Vec<String>>,
    pub author: Option<i32>,
    pub reference: Option<Vec<Reference>>,

    #[serde(flatten)]
    pub unknown: HashMap<String, Value>,
}

#[derive(Serialize, Deserialize, Clone, Debug, HasUnknown)]
pub struct WrittenContents {
    pub written_content: Option<Vec<WrittenContent>>,

    #[serde(flatten)]
    pub unknown: HashMap<String, Value>,
}

#[derive(Serialize, Deserialize, Clone, Debug, HasUnknown)]
pub struct Reference {
    pub id: Option<i32>,
    #[serde(alias = "type")]
    pub type_: Option<String>,

    #[serde(flatten)]
    pub unknown: HashMap<String, Value>,
}

impl Filler<df_st_core::WrittenContent, WrittenContent> for df_st_core::WrittenContent {
    fn add_missing_data(&mut self, source: &WrittenContent) {
        self.id.add_missing_data(&source.id);
        self.title.add_missing_data(&source.title);
        self.page_start.add_missing_data(&source.page_start);
        self.page_end.add_missing_data(&source.page_end);
        self.type_.add_missing_data(&source.type_);
        self.author.add_missing_data(&source.author);
        if let Some(styles) = &source.style {
            let mut content_styles: Vec<df_st_core::WCStyle> = Vec::new();
            for (local_id, style) in styles.iter().enumerate() {
                // Rename some of the names to match legends.xml and to have consistency.
                let style = match style.to_ascii_lowercase().as_ref() {
                    "rigid" => "mechanical".to_owned(),
                    "selfindulgent" => "self indulgent".to_owned(),
                    "ornate" => "florid".to_owned(),
                    "depressing" => "melancholy".to_owned(),
                    "ranting" => "rant".to_owned(),
                    "touching" => "tender".to_owned(),
                    "immature" => "puerile".to_owned(),
                    "scornful" => "sardonic".to_owned(),
                    _ => style.to_ascii_lowercase(),
                };
                content_styles.push(df_st_core::WCStyle {
                    written_content_id: source.id,
                    local_id: local_id as i32,
                    label: Some(style.to_owned()),
                    ..Default::default()
                });
            }
            self.style.add_missing_data(&content_styles);
        }
        self.reference.add_missing_data(&source.reference);
    }
}

impl Filler<df_st_core::WCReference, Reference> for df_st_core::WCReference {
    fn add_missing_data(&mut self, source: &Reference) {
        self.type_.add_missing_data(&source.type_);
        self.type_id.add_missing_data(&source.id);
        if let Some(source_type) = &source.type_ {
            if source.id.is_some() {
                let lowercase_type = source_type.to_ascii_lowercase();
                match lowercase_type.as_ref() {
                    "written_content" => self.written_content_id.add_missing_data(&source.id),
                    "historical_event" => self.he_id.add_missing_data(&source.id),
                    "poetic_form" => self.poetic_form_id.add_missing_data(&source.id),
                    "musical_form" => self.musical_form_id.add_missing_data(&source.id),
                    "dance_form" => self.dance_form_id.add_missing_data(&source.id),
                    "historical_figure" => self.hf_id.add_missing_data(&source.id),
                    "site" => self.site_id.add_missing_data(&source.id),
                    "entity" => self.entity_id.add_missing_data(&source.id),
                    "artifact" => self.artifact_id.add_missing_data(&source.id),
                    "subregion" => self.subregion_id.add_missing_data(&source.id),
                    _ => {
                        warn!("WrittenContent:Reference: Unknown type: {}", lowercase_type);
                    }
                }
            }
        }
    }

    fn add_missing_data_indexed(&mut self, source: &Reference, index: u64) {
        self.local_id.add_missing_data(&(index as i32));
        // Add the others from the function above
        self.add_missing_data(source);
    }
}

impl PartialEq<df_st_core::WrittenContent> for WrittenContent {
    fn eq(&self, other: &df_st_core::WrittenContent) -> bool {
        self.id == other.id
    }
}

// `self.id` refers to the `type_id`. This is correct.
#[allow(clippy::suspicious_operation_groupings)]
impl PartialEq<df_st_core::WCReference> for Reference {
    fn eq(&self, other: &df_st_core::WCReference) -> bool {
        self.id == other.type_id && self.type_ == other.type_
    }
}

impl Filler<Vec<df_st_core::WrittenContent>, WrittenContents> for Vec<df_st_core::WrittenContent> {
    fn add_missing_data(&mut self, source: &WrittenContents) {
        self.add_missing_data(&source.written_content);
    }
}

impl Filler<IndexMap<u64, df_st_core::WrittenContent>, WrittenContents>
    for IndexMap<u64, df_st_core::WrittenContent>
{
    fn add_missing_data(&mut self, source: &WrittenContents) {
        self.add_missing_data(&source.written_content);
    }
}