#[cfg(any(feature = "alloc", feature = "std"))]
use crate::model::capabilities::DisplayCapabilities;
#[cfg(not(any(feature = "alloc", feature = "std")))]
use crate::model::diagnostics::EdidWarning;
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::model::diagnostics::ParseWarning;
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::model::prelude::Vec;
pub use display_types::EdidVersion;
pub trait EdidSource {
fn base_block(&self) -> &[u8; 128];
fn extension_blocks(&self) -> impl Iterator<Item = &[u8; 128]>;
#[cfg(any(feature = "alloc", feature = "std"))]
fn propagate_parse_warnings(&self, _caps: &mut DisplayCapabilities) {}
}
#[derive(Debug, Clone)]
pub struct ParsedEdid {
pub base_block: [u8; 128],
#[cfg(any(feature = "alloc", feature = "std"))]
pub extensions: Vec<[u8; 128]>,
#[cfg(any(feature = "alloc", feature = "std"))]
pub warnings: Vec<ParseWarning>,
}
impl EdidSource for ParsedEdid {
fn base_block(&self) -> &[u8; 128] {
&self.base_block
}
fn extension_blocks(&self) -> impl Iterator<Item = &[u8; 128]> {
#[cfg(any(feature = "alloc", feature = "std"))]
{
self.extensions.iter()
}
#[cfg(not(any(feature = "alloc", feature = "std")))]
{
core::iter::empty::<&[u8; 128]>()
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
fn propagate_parse_warnings(&self, caps: &mut DisplayCapabilities) {
caps.warnings.extend(self.warnings.iter().cloned());
}
}
#[derive(Debug)]
pub struct ParsedEdidRef<'a> {
pub base_block: &'a [u8; 128],
pub(crate) raw_extensions: &'a [u8],
pub num_extensions: usize,
#[cfg(any(feature = "alloc", feature = "std"))]
pub warnings: Vec<ParseWarning>,
#[cfg(not(any(feature = "alloc", feature = "std")))]
pub warnings: [Option<EdidWarning>; 8],
#[cfg(not(any(feature = "alloc", feature = "std")))]
pub num_warnings: usize,
}
impl<'a> ParsedEdidRef<'a> {
pub fn extension_block(&self, i: usize) -> Option<&'a [u8; 128]> {
let start = i.checked_mul(128)?;
self.raw_extensions.get(start..start + 128)?.try_into().ok()
}
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn iter_warnings(&self) -> impl Iterator<Item = &ParseWarning> {
self.warnings.iter()
}
#[cfg(not(any(feature = "alloc", feature = "std")))]
pub fn iter_warnings(&self) -> impl Iterator<Item = &EdidWarning> {
self.warnings[..self.num_warnings].iter().flatten()
}
}
impl<'a> EdidSource for ParsedEdidRef<'a> {
fn base_block(&self) -> &[u8; 128] {
self.base_block
}
fn extension_blocks(&self) -> impl Iterator<Item = &[u8; 128]> {
(0..self.num_extensions).filter_map(|i| self.extension_block(i))
}
#[cfg(any(feature = "alloc", feature = "std"))]
fn propagate_parse_warnings(&self, caps: &mut DisplayCapabilities) {
caps.warnings.extend(self.warnings.iter().cloned());
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<'a> From<ParsedEdidRef<'a>> for ParsedEdid {
fn from(r: ParsedEdidRef<'a>) -> Self {
Self {
base_block: *r.base_block,
extensions: (0..r.num_extensions)
.filter_map(|i| r.extension_block(i))
.copied()
.collect(),
warnings: r.warnings,
}
}
}
#[cfg(not(any(feature = "alloc", feature = "std")))]
impl<'a> From<ParsedEdidRef<'a>> for ParsedEdid {
fn from(r: ParsedEdidRef<'a>) -> Self {
Self {
base_block: *r.base_block,
}
}
}