1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
use super::{Files, ResourceDescriptor, ResourceNames}; use crate::{FilesystemPath, ViewPathLocationExt}; use serde::{Deserialize, Serialize}; use std::hash::Hash; use yy_typings::{Tags, ViewPath, ViewPathLocation}; #[derive(Debug, Clone, Eq, Serialize, Deserialize, Default)] pub struct FolderGraph { pub name: String, pub path_to_parent: Option<ViewPathLocation>, pub tags: Tags, pub order: usize, pub folders: Vec<FolderGraph>, pub files: Files, } #[derive(Debug, Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Serialize, Deserialize, Hash)] pub enum Item { Folder, Resource, } impl PartialEq for FolderGraph { fn eq(&self, other: &Self) -> bool { self.name == other.name } } impl Hash for FolderGraph { fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.name.hash(state); } } impl FolderGraph { pub(super) fn root() -> FolderGraph { FolderGraph { name: "folders".to_string(), order: 0, path_to_parent: None, files: Files::new(), folders: vec![], tags: vec![], } } pub fn new(name: String, parent: ViewPathLocation, tags: Tags, order: usize) -> FolderGraph { FolderGraph { name, path_to_parent: Some(parent), tags, order, files: Files::new(), folders: vec![], } } pub fn view_path_location(&self) -> ViewPathLocation { match &self.path_to_parent { Some(parent_path) => parent_path.join(&self.name), None => ViewPathLocation::root_folder(), } } pub fn view_path(&self) -> ViewPath { let path = self.view_path_location(); ViewPath { name: self.name.clone(), path, } } pub(super) fn get_folder_by_fname_mut<'a>( &'a mut self, name: &str, ) -> Option<&'a mut FolderGraph> { if self.files.contains_name(name) { return Some(self); } for subfolder in self.folders.iter_mut() { if let Some(found) = subfolder.get_folder_by_fname_mut(name) { return Some(found); } } None } pub(super) fn get_folder_by_fname<'a>(&'a self, name: &str) -> Option<&'a FolderGraph> { if self.files.contains_name(name) { return Some(self); } for subfolder in self.folders.iter() { if let Some(found) = subfolder.get_folder_by_fname(name) { return Some(found); } } None } pub fn to_flat(&self, resource_names: &ResourceNames) -> FlatFolderGraph { let view_path = self.view_path(); FlatFolderGraph { path_to_parent: self.path_to_parent.clone(), folders: self.folders.iter().map(|v| v.view_path()).collect(), files: self .files .inner() .iter() .filter_map(|v| { resource_names .get(&v.name) .map(|rd| FlatResourceDescriptor { filesystem_path: v.clone(), resource_descriptor: rd.clone(), }) }) .collect(), view_path, } } } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct FlatFolderGraph { pub view_path: ViewPath, pub path_to_parent: Option<ViewPathLocation>, pub folders: Vec<ViewPath>, pub files: Vec<FlatResourceDescriptor>, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct FlatResourceDescriptor { pub filesystem_path: FilesystemPath, pub resource_descriptor: ResourceDescriptor, }