1use crate::{e2s_types::Version, E2sError};
4use std::{
5 fs::File,
6 io::{Read, Seek, Write},
7 path::Path,
8};
9
10pub trait EraFileFormat: Sized {
12 type EraGroup;
14
15 type Id: EraFileId;
17
18 fn version(&self) -> &Version;
20
21 fn group(&self) -> &Self::EraGroup;
23
24 fn id(&self) -> &Self::Id;
26
27 fn new(group: Self::EraGroup, id: Self::Id) -> Self;
29}
30
31pub trait EraFileId: Clone {
33 fn to_file_name(&self) -> String;
35
36 fn network_name(&self) -> &str;
38
39 fn start_number(&self) -> u64;
41
42 fn count(&self) -> u32;
44}
45
46pub trait StreamReader<R: Read + Seek>: Sized {
48 type File: EraFileFormat;
50
51 type Iterator;
53
54 fn new(reader: R) -> Self;
56
57 fn read(self, network_name: String) -> Result<Self::File, E2sError>;
59
60 fn iter(self) -> Self::Iterator;
62}
63
64pub trait FileReader: StreamReader<File> {
66 fn open<P: AsRef<Path>>(
68 path: P,
69 network_name: impl Into<String>,
70 ) -> Result<Self::File, E2sError> {
71 let file = File::open(path).map_err(E2sError::Io)?;
72 let reader = Self::new(file);
73 reader.read(network_name.into())
74 }
75}
76
77pub trait StreamWriter<W: Write>: Sized {
79 type File: EraFileFormat;
81
82 fn new(writer: W) -> Self;
84
85 fn write_version(&mut self) -> Result<(), E2sError>;
87
88 fn write_file(&mut self, file: &Self::File) -> Result<(), E2sError>;
90
91 fn flush(&mut self) -> Result<(), E2sError>;
93}
94
95pub trait FileWriter {
97 type File: EraFileFormat<Id: EraFileId>;
99
100 fn create<P: AsRef<Path>>(path: P, file: &Self::File) -> Result<(), E2sError>;
102
103 fn create_with_id<P: AsRef<Path>>(directory: P, file: &Self::File) -> Result<(), E2sError>;
105}
106
107impl<T: StreamWriter<File>> FileWriter for T {
108 type File = T::File;
109
110 fn create<P: AsRef<Path>>(path: P, file: &Self::File) -> Result<(), E2sError> {
112 let file_handle = File::create(path).map_err(E2sError::Io)?;
113 let mut writer = Self::new(file_handle);
114 writer.write_file(file)?;
115 Ok(())
116 }
117
118 fn create_with_id<P: AsRef<Path>>(directory: P, file: &Self::File) -> Result<(), E2sError> {
120 let filename = file.id().to_file_name();
121 let path = directory.as_ref().join(filename);
122 Self::create(path, file)
123 }
124}