1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Individual database record handling
//!
//! This includes the [`DatabaseRecord`] trait, to be implemented by types that represent record
//! headers for a given database type, and the [`pdb_record`] module, which implements that trait
//! for PDB/PRC record and resource header types.

use core::fmt::Debug;
use std::io::{self, Cursor};

use crate::header::DatabaseHeader;

pub mod pdb_record;

/// Helper trait for database record types
pub trait DatabaseRecord: Sized + Debug + sealed::DatabaseRecordHelpers {
	/// Read the record header from the given byte array
	fn from_bytes(hdr: &DatabaseHeader, rdr: &mut Cursor<&[u8]>) -> Result<Self, io::Error>;

	/// Write the record header to a new `Vec<u8>`
	fn to_bytes(&self) -> Result<Vec<u8>, io::Error>;

	/// Return the record's name, if known
	fn name_str(&self) -> Option<&str>;

	/// Return the record's attributes, if known
	fn attributes(&self) -> Option<RecordAttributes>;

	/// Return the length of the record's data, if known
	fn data_len(&self) -> Option<u32>;

	/// Return the unique id if the record is not a resource
	fn unique_id(&self) -> Option<u32>;

	/// Return the resource id if the record is a resource
	fn resource_id(&self) -> Option<u16>;

	/// Construct a record with the given parameters
	fn construct_record(
		attributes: RecordAttributes,
		unique_id: u32,
		data_offset: u32,
		data_len: Option<u32>,
	) -> Self;

	/// Construct a resource with the given parameters
	fn construct_resource(
		name: &[u8; 4],
		record_id: u16,
		data_offset: u32,
		data_len: Option<u32>,
	) -> Self;
}

mod sealed {

	pub trait DatabaseRecordHelpers {
		/// The length of the record header, in bytes
		fn struct_len(&self) -> usize;

		fn next_entry_data_offset(&self) -> usize;

		fn data_offset(&self) -> u32;
	}
}

pub(crate) use sealed::DatabaseRecordHelpers;

use self::pdb_record::RecordAttributes;