split borrow to prevent clone

This commit is contained in:
Quaternions 2024-12-31 03:36:33 -08:00
parent 716354df2b
commit 3ddd31a489
2 changed files with 20 additions and 16 deletions

View File

@ -6,15 +6,15 @@ fn _1()->Result<(),crate::v1::Error>{
let input=std::io::BufReader::new(file); let input=std::io::BufReader::new(file);
let mut bot_file=crate::v1::File::new(input).unwrap(); let mut bot_file=crate::v1::File::new(input).unwrap();
println!("header={:?}",bot_file.header); println!("header={:?}",bot_file.header);
for TimedBlockId{time,block_id} in bot_file.header.offline_blocks_timeline.clone(){ for &TimedBlockId{time,block_id} in &bot_file.header.offline_blocks_timeline{
println!("offline time={} block_id={:?}",time,block_id); println!("offline time={} block_id={:?}",time,block_id);
let block=bot_file.read_block(block_id)?; let block=bot_file.data.read_block(&bot_file.header,block_id)?;
// offline blocks include the following event types: // offline blocks include the following event types:
// World, Gravity, Run, Camera, Setting // World, Gravity, Run, Camera, Setting
} }
for TimedBlockId{time,block_id} in bot_file.header.realtime_blocks_timeline.clone(){ for &TimedBlockId{time,block_id} in &bot_file.header.realtime_blocks_timeline{
println!("realtime time={} block_id={:?}",time,block_id); println!("realtime time={} block_id={:?}",time,block_id);
let block=bot_file.read_block(block_id)?; let block=bot_file.data.read_block(&bot_file.header,block_id)?;
// realtime blocks include the following event types: // realtime blocks include the following event types:
// Input, Output, Sound // Input, Output, Sound
} }

View File

@ -345,31 +345,35 @@ pub struct FileHeader{
pub struct File<R:BinReaderExt>{ pub struct File<R:BinReaderExt>{
pub header:FileHeader, pub header:FileHeader,
//reference to the data pub data:FileData<R>,
data:R,
} }
impl<R:BinReaderExt> File<R>{ impl<R:BinReaderExt> File<R>{
pub fn new(mut input:R)->Result<File<R>,binrw::Error>{ pub fn new(mut data:R)->Result<File<R>,binrw::Error>{
Ok(File{ Ok(File{
header:input.read_le()?, header:data.read_le()?,
data:input, data:FileData{data},
}) })
} }
}
pub struct FileData<R:BinReaderExt>{
data:R,
}
impl<R:BinReaderExt> FileData<R>{
fn data_mut(&mut self)->&mut R{ fn data_mut(&mut self)->&mut R{
&mut self.data &mut self.data
} }
fn block_reader(&mut self,block_id:BlockId)->Result<binrw::io::TakeSeek<&mut R>,Error>{ fn block_reader(&mut self,header:&FileHeader,block_id:BlockId)->Result<binrw::io::TakeSeek<&mut R>,Error>{
if self.header.block_positions.len() as u32<=block_id.0{ if header.block_positions.len() as u32<=block_id.0{
return Err(Error::InvalidBlockId(block_id)) return Err(Error::InvalidBlockId(block_id))
} }
let block_start=self.header.block_positions[block_id.0 as usize] as u64; let block_start=header.block_positions[block_id.0 as usize] as u64;
let block_end=self.header.block_positions[block_id.0 as usize+1] as u64; let block_end=header.block_positions[block_id.0 as usize+1] as u64;
self.data.seek(std::io::SeekFrom::Start(block_start)).map_err(Error::Seek)?; self.data.seek(std::io::SeekFrom::Start(block_start)).map_err(Error::Seek)?;
Ok(self.data_mut().take_seek(block_end-block_start)) Ok(self.data_mut().take_seek(block_end-block_start))
} }
pub fn read_block(&mut self,block_id:BlockId)->Result<Block,Error>{ pub fn read_block(&mut self,header:&FileHeader,block_id:BlockId)->Result<Block,Error>{
let data=self.block_reader(block_id)?; let data=self.block_reader(header,block_id)?;
let block=Block::read(data).map_err(Error::InvalidData)?; let block=Block::read(data).map_err(Error::InvalidData)?;
Ok(block) Ok(block)
} }