use std::io::{Read, Seek, Write};
use crate::{Header, PropertyTagPartial, Result, SaveGameArchive, StructType, VersionInfo};
pub trait ArchiveType: Clone + PartialEq + std::fmt::Debug + Default + serde::Serialize {
type ObjectRef: Clone
+ PartialEq
+ std::fmt::Debug
+ serde::Serialize
+ for<'de> serde::Deserialize<'de>;
type SoftObjectPath: Clone
+ PartialEq
+ std::fmt::Debug
+ serde::Serialize
+ for<'de> serde::Deserialize<'de>;
}
pub trait ArchiveReader: Read + Seek {
type ArchiveType: ArchiveType;
fn version(&self) -> &dyn VersionInfo;
fn scope(&mut self) -> &mut crate::Scope;
fn get_type_or(&mut self, default: &StructType) -> Result<StructType>;
fn read_string(&mut self) -> Result<String>;
fn read_string_trailing(&mut self) -> Result<(String, Vec<u8>)>;
fn read_object_ref(&mut self) -> Result<<Self::ArchiveType as ArchiveType>::ObjectRef>;
fn read_soft_object_path(
&mut self,
) -> Result<<Self::ArchiveType as ArchiveType>::SoftObjectPath>;
fn record_schema(&mut self, path: String, tag: PropertyTagPartial);
fn path(&self) -> String;
fn log(&self) -> bool {
false
}
fn error_to_raw(&self) -> bool {
false
}
}
pub trait ArchiveWriter: Write + Seek {
type ArchiveType: ArchiveType;
fn version(&self) -> &dyn VersionInfo;
fn set_version(&mut self, header: Header);
fn scope(&mut self) -> &mut crate::Scope;
fn write_string(&mut self, string: &str) -> Result<()>;
fn write_string_trailing(&mut self, string: &str, trailing: Option<&[u8]>) -> Result<()>;
fn write_object_ref(
&mut self,
object_ref: &<Self::ArchiveType as ArchiveType>::ObjectRef,
) -> Result<()>;
fn write_soft_object_path(
&mut self,
soft_object_path: &<Self::ArchiveType as ArchiveType>::SoftObjectPath,
) -> Result<()>;
fn get_schema(&self, path: &str) -> Option<PropertyTagPartial>;
fn path(&self) -> String;
fn log(&self) -> bool {
false
}
}
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize)]
pub struct SaveGameArchiveType;
impl ArchiveType for SaveGameArchiveType {
type ObjectRef = String;
type SoftObjectPath = crate::SoftObjectPath;
}
impl<R> ArchiveReader for SaveGameArchive<R>
where
R: Read + Seek,
{
type ArchiveType = SaveGameArchiveType;
fn version(&self) -> &dyn VersionInfo {
SaveGameArchive::version(self)
}
fn scope(&mut self) -> &mut crate::Scope {
&mut self.scope
}
fn get_type_or(&mut self, default: &StructType) -> Result<StructType> {
SaveGameArchive::get_type_or(self, default)
}
fn read_string(&mut self) -> Result<String> {
crate::read_string(self)
}
fn read_string_trailing(&mut self) -> Result<(String, Vec<u8>)> {
crate::read_string_trailing(self)
}
fn read_object_ref(&mut self) -> Result<String> {
crate::read_string(self)
}
fn read_soft_object_path(&mut self) -> Result<crate::SoftObjectPath> {
crate::SoftObjectPath::read(self)
}
fn record_schema(&mut self, path: String, tag: PropertyTagPartial) {
self.schemas.borrow_mut().record(path, tag);
}
fn path(&self) -> String {
self.scope.path()
}
fn log(&self) -> bool {
SaveGameArchive::log(self)
}
fn error_to_raw(&self) -> bool {
SaveGameArchive::error_to_raw(self)
}
}
impl<W> ArchiveWriter for SaveGameArchive<W>
where
W: Write + Seek,
{
type ArchiveType = SaveGameArchiveType;
fn version(&self) -> &dyn VersionInfo {
SaveGameArchive::version(self)
}
fn set_version(&mut self, header: Header) {
SaveGameArchive::set_version(self, header)
}
fn scope(&mut self) -> &mut crate::Scope {
&mut self.scope
}
fn write_string(&mut self, string: &str) -> Result<()> {
crate::write_string(self, string)
}
fn write_string_trailing(&mut self, string: &str, trailing: Option<&[u8]>) -> Result<()> {
crate::write_string_trailing(self, string, trailing)
}
fn write_object_ref(&mut self, object_ref: &String) -> Result<()> {
crate::write_string(self, object_ref)
}
fn write_soft_object_path(&mut self, soft_object_path: &crate::SoftObjectPath) -> Result<()> {
soft_object_path.write(self)
}
fn get_schema(&self, path: &str) -> Option<PropertyTagPartial> {
self.schemas.borrow().get(path).cloned()
}
fn path(&self) -> String {
self.scope.path()
}
fn log(&self) -> bool {
SaveGameArchive::log(self)
}
}