espers/records/
ipds.rs

1use super::{get_cursor, Flags};
2use crate::error::Error;
3use crate::fields::EDID;
4use binrw::{binrw, BinRead};
5use serde_derive::{Deserialize, Serialize};
6use std::fmt;
7use std::io::Cursor;
8
9#[binrw]
10#[derive(Debug, Clone, Serialize, Deserialize)]
11#[brw(little, magic = b"IPDS")]
12pub struct IPDS {
13    pub size: u32,
14    pub flags: Flags,
15    pub form_id: u32,
16    pub timestamp: u16,
17    pub version_control: u16,
18    pub internal_version: u16,
19    pub unknown: u16,
20    #[br(count = size)]
21    pub data: Vec<u8>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct ImpactDataSet {
26    pub edid: Option<String>,
27}
28
29impl fmt::Display for ImpactDataSet {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        write!(
32            f,
33            "ImpactDataSet ({})",
34            self.edid.as_deref().unwrap_or("~")
35        )
36    }
37}
38
39impl TryFrom<IPDS> for ImpactDataSet {
40    type Error = Error;
41
42    fn try_from(raw: IPDS) -> Result<Self, Self::Error> {
43        let data = get_cursor(&raw.data, raw.flags.contains(Flags::COMPRESSED));
44        let mut cursor = Cursor::new(&data);
45
46        let edid = EDID::read(&mut cursor)
47            .ok()
48            .map(TryInto::try_into)
49            .transpose()?;
50
51        Ok(Self { edid })
52    }
53}