matter-clusters 0.3.0

Matter protocol cluster definitions (generated from the spec).
Documentation
//! Identify cluster (0x0003).
//! @generated by `cargo xtask codegen` — do not edit.

#![allow(
    clippy::all,
    clippy::pedantic,
    dead_code,
    unreachable_pub,
    unused_imports
)]

use crate::datatypes::SemanticTagStruct;
use crate::error::ClusterError;
use crate::types::Nullable;
use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};

/// Cluster ID.
pub const CLUSTER_ID: u32 = 0x0003;
/// Cluster revision.
pub const CLUSTER_REVISION: u16 = 6;

/// Command IDs (requests and responses).
pub mod command_id {
    /// `Identify` (request).
    pub const IDENTIFY: u32 = 0x00;
    /// `TriggerEffect` (request).
    pub const TRIGGER_EFFECT: u32 = 0x40;
}

/// Attribute IDs (cluster-specific).
pub mod attribute_id {
    /// `IdentifyTime`.
    pub const IDENTIFY_TIME: u32 = 0x0000;
    /// `IdentifyType`.
    pub const IDENTIFY_TYPE: u32 = 0x0001;
}

/// `EffectIdentifierEnum` (enum8).
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EffectIdentifierEnum {
    /// Blink = 0.
    Blink,
    /// Breathe = 1.
    Breathe,
    /// Okay = 2.
    Okay,
    /// ChannelChange = 11.
    ChannelChange,
    /// FinishEffect = 254.
    FinishEffect,
    /// StopEffect = 255.
    StopEffect,
    /// A value not known to this codegen revision.
    Unknown(u8),
}

impl EffectIdentifierEnum {
    /// Decode from its raw discriminant (unknown → `Unknown`).
    #[must_use]
    pub fn from_raw(v: u8) -> Self {
        match v {
            0 => Self::Blink,
            1 => Self::Breathe,
            2 => Self::Okay,
            11 => Self::ChannelChange,
            254 => Self::FinishEffect,
            255 => Self::StopEffect,
            other => Self::Unknown(other),
        }
    }
    /// The raw discriminant.
    #[must_use]
    pub fn to_raw(self) -> u8 {
        match self {
            Self::Blink => 0,
            Self::Breathe => 1,
            Self::Okay => 2,
            Self::ChannelChange => 11,
            Self::FinishEffect => 254,
            Self::StopEffect => 255,
            Self::Unknown(v) => v,
        }
    }
}

/// `EffectVariantEnum` (enum8).
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EffectVariantEnum {
    /// Default = 0.
    Default,
    /// A value not known to this codegen revision.
    Unknown(u8),
}

impl EffectVariantEnum {
    /// Decode from its raw discriminant (unknown → `Unknown`).
    #[must_use]
    pub fn from_raw(v: u8) -> Self {
        match v {
            0 => Self::Default,
            other => Self::Unknown(other),
        }
    }
    /// The raw discriminant.
    #[must_use]
    pub fn to_raw(self) -> u8 {
        match self {
            Self::Default => 0,
            Self::Unknown(v) => v,
        }
    }
}

/// `IdentifyTypeEnum` (enum8).
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum IdentifyTypeEnum {
    /// None = 0.
    None,
    /// LightOutput = 1.
    LightOutput,
    /// VisibleIndicator = 2.
    VisibleIndicator,
    /// AudibleBeep = 3.
    AudibleBeep,
    /// Display = 4.
    Display,
    /// Actuator = 5.
    Actuator,
    /// A value not known to this codegen revision.
    Unknown(u8),
}

impl IdentifyTypeEnum {
    /// Decode from its raw discriminant (unknown → `Unknown`).
    #[must_use]
    pub fn from_raw(v: u8) -> Self {
        match v {
            0 => Self::None,
            1 => Self::LightOutput,
            2 => Self::VisibleIndicator,
            3 => Self::AudibleBeep,
            4 => Self::Display,
            5 => Self::Actuator,
            other => Self::Unknown(other),
        }
    }
    /// The raw discriminant.
    #[must_use]
    pub fn to_raw(self) -> u8 {
        match self {
            Self::None => 0,
            Self::LightOutput => 1,
            Self::VisibleIndicator => 2,
            Self::AudibleBeep => 3,
            Self::Display => 4,
            Self::Actuator => 5,
            Self::Unknown(v) => v,
        }
    }
}

/// Decode the `IdentifyTime` attribute value.
///
/// # Errors
/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
pub fn decode_identify_time(tlv: &[u8]) -> Result<u16, ClusterError> {
    let mut r = TlvReader::new(tlv);
    match r.next()? {
        Some(Element::Scalar {
            value: Value::Uint(v),
            ..
        }) => Ok(u16::try_from(v).map_err(|_| ClusterError::InvalidLength("IdentifyTime"))?),
        _ => Err(ClusterError::UnexpectedType {
            context: "IdentifyTime",
        }),
    }
}

/// Encode the `IdentifyTime` attribute value as a standalone TLV element.
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
pub fn encode_identify_time(value: u16) -> Vec<u8> {
    let mut buf = Vec::new();
    let mut w = TlvWriter::new(&mut buf);
    w.put_uint(Tag::Anonymous, u64::from(value))
        .expect("infallible: vec writer");
    buf
}

/// Decode the `IdentifyType` attribute value.
///
/// # Errors
/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
pub fn decode_identify_type(tlv: &[u8]) -> Result<IdentifyTypeEnum, ClusterError> {
    let mut r = TlvReader::new(tlv);
    match r.next()? {
        Some(Element::Scalar {
            value: Value::Uint(v),
            ..
        }) => Ok(IdentifyTypeEnum::from_raw(
            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("IdentifyType"))?,
        )),
        _ => Err(ClusterError::UnexpectedType {
            context: "IdentifyType",
        }),
    }
}

/// Encode the `Identify` command request payload.
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
pub fn encode_identify(identify_time: u16) -> Vec<u8> {
    let mut buf = Vec::new();
    let mut w = TlvWriter::new(&mut buf);
    w.start_structure(Tag::Anonymous)
        .expect("infallible: vec writer");
    w.put_uint(Tag::Context(0), u64::from(identify_time))
        .expect("infallible: vec writer");
    w.end_container().expect("infallible: vec writer");
    buf
}

/// Encode the `TriggerEffect` command request payload.
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
pub fn encode_trigger_effect(
    effect_identifier: EffectIdentifierEnum,
    effect_variant: EffectVariantEnum,
) -> Vec<u8> {
    let mut buf = Vec::new();
    let mut w = TlvWriter::new(&mut buf);
    w.start_structure(Tag::Anonymous)
        .expect("infallible: vec writer");
    w.put_uint(Tag::Context(0), u64::from(effect_identifier.to_raw()))
        .expect("infallible: vec writer");
    w.put_uint(Tag::Context(1), u64::from(effect_variant.to_raw()))
        .expect("infallible: vec writer");
    w.end_container().expect("infallible: vec writer");
    buf
}