use std::{collections::HashMap, path::PathBuf}; use serde::{ser::SerializeStruct, Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Plan { plan: Vec, current: usize, #[serde(flatten)] pub metadata: PlanMetadata, } #[derive(Deserialize, Debug, Clone)] pub struct PlanMetadata { stored_path: Option, update_url: Option, pub latest_server_etag: Option, identifier: Option, } impl PlanMetadata { pub fn set_stored_path(&mut self, file: Option) { self.stored_path = file; } } impl Serialize for PlanMetadata { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut state = serializer.serialize_struct("PlanMetadata", 5)?; state.serialize_field("update_url", &self.update_url)?; state.serialize_field("stored_path", &self.stored_path)?; state.serialize_field("latest_server_etag", &self.latest_server_etag)?; state.serialize_field("identifier", &self.identifier)?; if let Some(path) = &self.stored_path { if let Some(name) = path.file_name() { state.serialize_field("name", &name.to_str())?; } } state.end() } } impl From for Option { fn from(metadata: PlanMetadata) -> Self { Some(serde_json::from_slice(&std::fs::read(metadata.stored_path?).ok()?).ok()?) } } impl Plan { pub fn set_stored_path(&mut self, file: Option) { self.metadata.stored_path = file; } } #[derive(Debug, Deserialize, Serialize, Clone)] pub struct PlanElement { area_key: String, notes: String, #[serde(default = "PlanElement::generate_uuid")] uuid: uuid::Uuid, #[serde(default = "PlanElement::edited")] edited: bool, anchor_act: Option, } impl PlanElement { pub fn generate_uuid() -> uuid::Uuid { uuid::Uuid::new_v4() } pub fn edited() -> bool { false } } #[allow(dead_code)] #[derive(Debug, Deserialize)] struct OldPlanElement { area: OldArea, note: String, } #[allow(dead_code)] #[derive(Debug, Deserialize)] struct OldPlan { elements: Vec, position: usize, } #[derive(Debug, Deserialize)] struct OldArea { _rid: usize, } #[allow(dead_code)] pub fn convert_old(path: PathBuf) -> Option { let plan: OldPlan = serde_json::from_str(&std::fs::read_to_string(path).expect("Could not convert old")) .expect("could not convert old"); let map = poe_data::world_area::load_world_areas_map(include_str!( "../../data/processed_world_areas.json" )); let map = map .iter() .map(|(k, v)| (v.key_id, k)) .collect::>(); Some(Plan { current: plan.position, plan: plan .elements .into_iter() .map(|plan_element| PlanElement { area_key: map[&plan_element.area._rid].to_owned(), notes: plan_element.note, uuid: PlanElement::generate_uuid(), edited: PlanElement::edited(), anchor_act: None, }) .collect::>(), metadata: PlanMetadata { stored_path: None, update_url: None, latest_server_etag: None, identifier: None, }, }) }