use serde::ser::{Serialize, SerializeMap, Serializer}; use crate::fast_hash_map::FastHashMap; use crate::global_lib_table::{GlobalLibIndex, GlobalLibTable}; use crate::serialization_helpers::SerializableSingleValueColumn; use crate::thread_string_table::ThreadInternalStringIndex; use crate::thread_string_table::ThreadStringTable; #[derive(Debug, Clone, Default)] pub struct ResourceTable { resource_libs: Vec, resource_names: Vec, lib_to_resource: FastHashMap, } impl ResourceTable { pub fn new() -> Self { Default::default() } pub fn resource_for_lib( &mut self, lib_index: GlobalLibIndex, global_libs: &GlobalLibTable, thread_string_table: &mut ThreadStringTable, ) -> ResourceIndex { let resource_libs = &mut self.resource_libs; let resource_names = &mut self.resource_names; *self.lib_to_resource.entry(lib_index).or_insert_with(|| { let resource = ResourceIndex(resource_libs.len() as u32); let lib_name = &global_libs.get_lib(lib_index).unwrap().name; resource_libs.push(lib_index); resource_names.push(thread_string_table.index_for_string(lib_name)); resource }) } } impl Serialize for ResourceTable { fn serialize(&self, serializer: S) -> Result { const RESOURCE_TYPE_LIB: u32 = 1; let len = self.resource_libs.len(); let mut map = serializer.serialize_map(None)?; map.serialize_entry("length", &len)?; map.serialize_entry("lib", &self.resource_libs)?; map.serialize_entry("name", &self.resource_names)?; map.serialize_entry("host", &SerializableSingleValueColumn((), len))?; map.serialize_entry( "type", &SerializableSingleValueColumn(RESOURCE_TYPE_LIB, len), )?; map.end() } } #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)] pub struct ResourceIndex(u32); impl Serialize for ResourceIndex { fn serialize(&self, serializer: S) -> Result { serializer.serialize_u32(self.0) } }