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