diff --git a/crates/common/src/abstractions/assets.rs b/crates/common/src/abstractions/assets.rs index 91b22232..6c14e565 100644 --- a/crates/common/src/abstractions/assets.rs +++ b/crates/common/src/abstractions/assets.rs @@ -1,15 +1,6 @@ //! Asset management for the engine -/// An error that can occur when loading an asset -#[derive(Debug)] -pub enum AssetError { - /// The asset could not be found - NotFound, - /// The asset could not be loaded - LoadFailed, - /// The asset is not of the expected type - TypeMismatch, -} +use crate::{FileSystemError, FromStream, ToVirtualPath}; /// Represents an asset that can be loaded and used by the engine pub trait Asset {} @@ -17,3 +8,21 @@ pub trait Asset {} /// A manager for assets #[derive(Default)] pub struct AssetManager {} + +impl AssetManager { + /// Loads an asset from the given path + pub fn load(&self, path: impl ToVirtualPath) -> Result { + let path = path.to_virtual_path(); + let mut stream = path.open_input_stream().map_err(|_| AssetError::NotFound)?; + + A::from_stream(&mut stream).map_err(|_| AssetError::LoadFailed) + } +} + +/// An error that can occur when loading an asset +#[derive(Debug)] +pub enum AssetError { + NotFound, + LoadFailed, + TypeMismatch, +} diff --git a/crates/common/src/io/streams.rs b/crates/common/src/io/streams.rs index 84184a03..f68168a1 100644 --- a/crates/common/src/io/streams.rs +++ b/crates/common/src/io/streams.rs @@ -4,30 +4,46 @@ use crate::{FileSystemError, ToVirtualPath}; /// Allows a type to be imported from a VFS stream. pub trait FromStream: Sized { - /// Imports the type from a stream. - fn from_stream(stream: &mut dyn InputStream) -> Result; - /// Imports the type from a path. - fn from_path(path: impl ToVirtualPath) -> Result { + fn from_path(path: impl ToVirtualPath) -> Result { let path = path.to_virtual_path(); let mut stream = path.open_input_stream()?; Self::from_stream(&mut stream) } + + /// Imports the type from a byte array. + fn from_bytes(bytes: &[u8]) -> Result { + let mut stream = std::io::Cursor::new(bytes); + + Self::from_stream(&mut stream) + } + + /// Imports the type from a stream. + fn from_stream(stream: &mut dyn InputStream) -> Result; } /// Allows a type to be exported to a VFS stream. pub trait ToStream: Sized { - /// Exports the type to a stream. - fn to_stream(&self, stream: &mut dyn OutputStream) -> Result<(), FileSystemError>; - /// Exports the type to a path. - fn to_path(&self, path: impl ToVirtualPath) -> Result<(), FileSystemError> { + fn to_path(&self, path: impl ToVirtualPath) -> Result<(), StreamError> { let path = path.to_virtual_path(); let mut stream = path.open_output_stream()?; self.to_stream(&mut stream) } + + /// Exports the type to a byte array. + fn to_bytes(&self) -> Result, StreamError> { + let mut stream = std::io::Cursor::new(Vec::new()); + + self.to_stream(&mut stream)?; + + Ok(stream.into_inner()) + } + + /// Exports the type to a stream. + fn to_stream(&self, stream: &mut dyn OutputStream) -> Result<(), StreamError>; } /// Represents an error that occurred while reading or writing to a stream. @@ -35,7 +51,7 @@ pub trait ToStream: Sized { pub enum StreamError { UnexpectedEof, UnexpectedEncoding, - FailedToDeserialize, + GeneralFailure, } impl From for StreamError { @@ -52,6 +68,13 @@ impl From for StreamError { } } +impl From for StreamError { + #[inline] + fn from(_: FileSystemError) -> Self { + Self::GeneralFailure + } +} + /// A stream for reading from some [`VirtualPath`]. pub trait InputStream: Seek + BufRead { fn read_u8(&mut self) -> Result; @@ -70,8 +93,8 @@ pub trait InputStream: Seek + BufRead { fn read_f64(&mut self) -> Result; fn read_string(&mut self) -> Result; fn read_bytes(&mut self, amount: usize) -> Result, StreamError>; - fn to_buffer(&mut self) -> Result, StreamError>; - fn to_string(&mut self) -> Result; + fn to_buffer(self) -> Result, StreamError>; + fn to_string(self) -> Result; } macro_rules! impl_read { @@ -113,7 +136,7 @@ impl InputStream for T { #[inline] fn read_usize(&mut self) -> Result { - impl_read!(self, std::mem::size_of::(), usize) + impl_read!(self, size_of::(), usize) } #[inline] @@ -143,7 +166,7 @@ impl InputStream for T { #[inline] fn read_isize(&mut self) -> Result { - impl_read!(self, std::mem::size_of::(), isize) + impl_read!(self, size_of::(), isize) } #[inline] @@ -173,7 +196,7 @@ impl InputStream for T { Ok(buffer) } - fn to_buffer(&mut self) -> Result, StreamError> { + fn to_buffer(mut self) -> Result, StreamError> { let mut buffer = Vec::new(); self.read_to_end(&mut buffer)?; @@ -181,7 +204,7 @@ impl InputStream for T { Ok(buffer) } - fn to_string(&mut self) -> Result { + fn to_string(mut self) -> Result { let mut buffer = String::new(); self.read_to_string(&mut buffer)?; diff --git a/crates/common/src/io/virtualfs.rs b/crates/common/src/io/virtualfs.rs index e1f8ea67..ad924a45 100644 --- a/crates/common/src/io/virtualfs.rs +++ b/crates/common/src/io/virtualfs.rs @@ -11,27 +11,6 @@ use crate::{Singleton, StringName, ToStringName}; mod local; mod memory; -/// A potential error that can occur when interacting with a [`FileSystem`]. -#[derive(Debug)] -pub enum FileSystemError { - GeneralError(std::io::Error), - StreamError(super::StreamError), -} - -impl From for FileSystemError { - #[inline] - fn from(error: std::io::Error) -> Self { - Self::GeneralError(error) - } -} - -impl From for FileSystemError { - #[inline] - fn from(error: super::StreamError) -> Self { - Self::StreamError(error) - } -} - /// Represents a type capable of acting as a file system. /// /// File systems are resolved from the scheme used in [`VirtualPath`]s, and @@ -187,17 +166,14 @@ impl VirtualPath { /// Attempts to read all bytes from the given path. pub fn read_all_bytes(&self) -> Result, FileSystemError> { - let mut buffer = Vec::new(); - let mut stream = self.open_input_stream()?; - - stream.read_to_end(&mut buffer)?; + let stream = self.open_input_stream()?; - Ok(buffer) + Ok(stream.to_buffer()?) } /// Attempts to read all text from the given path. pub fn read_all_text(&self) -> Result { - let mut stream = self.open_input_stream()?; + let stream = self.open_input_stream()?; Ok(stream.to_string()?) } @@ -251,6 +227,27 @@ impl Into for String { } } +/// A potential error that can occur when interacting with a [`FileSystem`]. +#[derive(Debug)] +pub enum FileSystemError { + GeneralError(std::io::Error), + StreamError(super::StreamError), +} + +impl From for FileSystemError { + #[inline] + fn from(error: std::io::Error) -> Self { + Self::GeneralError(error) + } +} + +impl From for FileSystemError { + #[inline] + fn from(error: super::StreamError) -> Self { + Self::StreamError(error) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/graphics/src/fonts/otf.rs b/crates/graphics/src/fonts/otf.rs index 2bae874f..28f63f45 100644 --- a/crates/graphics/src/fonts/otf.rs +++ b/crates/graphics/src/fonts/otf.rs @@ -1,4 +1,4 @@ -use common::{FastHashMap, FileSystemError, FromStream, InputStream}; +use common::{FastHashMap, FromStream, InputStream, StreamError}; /// A single glyph in an OpenType font. struct OpenTypeGlyph {} @@ -9,7 +9,7 @@ pub struct OpenTypeFont { } impl FromStream for OpenTypeFont { - fn from_stream(stream: &mut dyn InputStream) -> Result { + fn from_stream(stream: &mut dyn InputStream) -> Result { let _a = stream.read_u16()?; let _b = stream.read_u16()?;