khora_core/vfs/
mod.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Virtual File System (VFS) module for fast, in-memory asset metadata access.
16//!
17//! This module provides the [`VirtualFileSystem`] struct, which loads and manages
18//! an index of asset metadata for efficient runtime queries. It is designed to
19//! support asset loading and management by offering O(1) lookups of asset metadata
20//! using asset UUIDs. The VFS is typically initialized from a packed binary index
21//! file and serves as the primary source of truth for asset metadata in the engine.
22
23use crate::asset::{AssetMetadata, AssetUUID};
24use bincode;
25use std::collections::HashMap;
26
27/// The runtime representation of the asset index (`index.bin`).
28///
29/// The Virtual File System is a service that provides fast, in-memory access
30/// to the metadata of all assets available in the packed data. It is the
31/// primary source of truth for the `AssetAgent` when it needs to make decisions
32/// about loading assets.
33#[derive(Debug)]
34pub struct VirtualFileSystem {
35    /// The internal index mapping asset UUIDs to their metadata.
36    /// This provides O(1) average-time lookups.
37    index: HashMap<AssetUUID, AssetMetadata>,
38}
39
40impl VirtualFileSystem {
41    /// Creates a new `VirtualFileSystem` by loading and parsing an index file from its raw bytes.
42    ///
43    /// This function is the entry point for the runtime asset system. It takes the
44    /// binary data from `index.bin` and builds the in-memory lookup table.
45    ///
46    /// # Errors
47    /// Returns a `DecodeError` if the byte slice is not a valid, bincode-encoded
48    /// list of `AssetMetadata`.
49    pub fn new(index_bytes: &[u8]) -> Result<Self, bincode::error::DecodeError> {
50        let config = bincode::config::standard();
51        // First, decode the bytes into a flat list of metadata.
52        let (metadata_vec, _): (Vec<AssetMetadata>, _) =
53            bincode::serde::decode_from_slice(index_bytes, config)?;
54
55        // Then, build the HashMap for fast lookups.
56        let index = metadata_vec
57            .into_iter()
58            .map(|meta| (meta.uuid, meta))
59            .collect();
60
61        Ok(Self { index })
62    }
63
64    /// Retrieves the metadata for a given asset UUID.
65    ///
66    /// This is the primary query method used by the `AssetAgent`.
67    pub fn get_metadata(&self, uuid: &AssetUUID) -> Option<&AssetMetadata> {
68        self.index.get(uuid)
69    }
70}