Emptying out text, as I'd like to wipe these, please.
To represent the various types of records, you probably want an enum.
enum Record {
FooRecord { fields... },
BarRecord { fields... },
}
As for parsing each kind of record, you might want to try out the byteorder
crate instead of using from_be_bytes
directly, although both are good ways of doing it. Regarding doing different things depending on record type, I'd first read the identification header, and then I'd have a big match on the kind of record and have a function per record you call from the match.
Regarding the hash map, that depends on the details. You should use a hash map if you have a variable number of keys you don't know ahead of time, and a struct if you know all the fields when writing the code.
Here's an example using the byteorder
crate. I guessed that it was big endian.
use std::io::{BufRead, Result};
use byteorder::{BigEndian, ReadBytesExt};
struct Table1Record {
len: u16,
seg: u16,
flg: u8,
rty: u8,
tme: u32,
dte: u32,
sid: u32,
}
impl Table1Record {
/// Read from the provided buffered input stream.
pub fn read_from<R: BufRead>(reader: &mut R) -> Result<Table1Record> {
let len = reader.read_u16::<BigEndian>()?;
let seg = reader.read_u16::<BigEndian>()?;
let flg = reader.read_u8()?;
let rty = reader.read_u8()?;
let tme = reader.read_u32::<BigEndian>()?;
let dte = reader.read_u32::<BigEndian>()?;
let sid = reader.read_u32::<BigEndian>()?;
Ok(Table1Record {
len, seg, flg, rty, tme, dte, sid,
})
}
}
Note that it often makes sense to make a struct like the above for each table, and you enum can then look like this:
enum Record {
FooRecord(FooRecordStruct),
BarRecord(BarRecordStruct),
}
If you have variable length data, a Vec or HashMap can indeed make sense depending on the shape of your data. I'm imagining something like this:
struct Record {
header: Header,
body: RecordBody,
}
enum RecordBody {
FooRecord(FooRecordStruct),
BarRecord(BarRecordStruct),
}
impl Record {
pub fn read_from<R: BufRead>(reader: &mut R) -> Result<Record> {
let header = Header::read_from(reader)?;
let body = match header.kind {
0 => RecordBody::FooRecord(FooRecordStruct::read_from(reader)?),
1 => RecordBody::BarRecord(BarRecordStruct::read_from(reader)?),
kind => return Err(Error::new(ErrorKind::InvalidData, format!("Invalid kind: {}", kind)))
};
Ok(Record {
header,
body,
})
}
}
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.