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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
 * SPDX-License-Identifier: MIT
 */
use std::io::{Seek, Write};

use pipewire_wrapper_proc_macro::object_type_impl;

use crate::enum_wrapper;
use crate::spa::pod::id::PodIdRef;
use crate::spa::pod::object::prop::Prop;
use crate::spa::pod::object::{PodPropKeyType, PodPropRef};
use crate::spa::pod::string::PodStringRef;
use crate::spa::pod::struct_::PodStructRef;
use crate::spa::pod::{BasicTypePod, PodBoolRef, PodError, PodRef, PodResult};
use crate::wrapper::RawWrapper;

#[repr(u32)]
#[derive(Debug)]
#[allow(non_camel_case_types)]
#[object_type_impl(OBJECT_PROP_INFO)]
pub enum ObjectPropInfoType<'a> {
    ID(&'a PodIdRef<Prop>) = PropInfo::ID.raw,
    NAME(&'a PodStringRef) = PropInfo::NAME.raw,
    TYPE(&'a PodRef) = PropInfo::TYPE.raw,
    LABELS(&'a PodStructRef) = PropInfo::LABELS.raw,
    CONTAINER(&'a PodIdRef<u32>) = PropInfo::CONTAINER.raw,
    PARAMS(&'a PodBoolRef) = PropInfo::PARAMS.raw,
    DESCRIPTION(&'a PodStringRef) = PropInfo::DESCRIPTION.raw,
}

impl<'a> PodPropKeyType<'a> for ObjectPropInfoType<'a> {
    fn write_prop<W>(&self, buffer: &mut W) -> PodResult<()>
    where
        W: Write + Seek,
    {
        match self {
            ObjectPropInfoType::ID(pod) => Self::write_pod_prop(buffer, PropInfo::ID.raw, 0, pod),
            ObjectPropInfoType::NAME(pod) => {
                Self::write_pod_prop(buffer, PropInfo::NAME.raw, 0, pod)
            }
            ObjectPropInfoType::TYPE(pod) => {
                Self::write_pod_prop(buffer, PropInfo::TYPE.raw, 0, pod)
            }
            ObjectPropInfoType::LABELS(pod) => {
                Self::write_pod_prop(buffer, PropInfo::LABELS.raw, 0, pod)
            }
            ObjectPropInfoType::CONTAINER(pod) => {
                Self::write_pod_prop(buffer, PropInfo::CONTAINER.raw, 0, pod)
            }
            ObjectPropInfoType::PARAMS(pod) => {
                Self::write_pod_prop(buffer, PropInfo::PARAMS.raw, 0, pod)
            }
            ObjectPropInfoType::DESCRIPTION(pod) => {
                Self::write_pod_prop(buffer, PropInfo::DESCRIPTION.raw, 0, pod)
            }
        }
    }
}

impl<'a> TryFrom<&'a PodPropRef<'a, ObjectPropInfoType<'a>>> for ObjectPropInfoType<'a> {
    type Error = PodError;

    fn try_from(value: &'a PodPropRef<'a, ObjectPropInfoType<'a>>) -> Result<Self, Self::Error> {
        unsafe {
            match PropInfo::from_raw(value.raw.key) {
                PropInfo::ID => Ok(ObjectPropInfoType::ID(value.pod().cast()?)),
                PropInfo::NAME => Ok(ObjectPropInfoType::NAME(value.pod().cast()?)),
                PropInfo::TYPE => Ok(ObjectPropInfoType::TYPE(value.pod().cast()?)),
                PropInfo::LABELS => Ok(ObjectPropInfoType::LABELS(value.pod().cast()?)),
                PropInfo::CONTAINER => Ok(ObjectPropInfoType::CONTAINER(value.pod().cast()?)),
                PropInfo::PARAMS => Ok(ObjectPropInfoType::PARAMS(value.pod().cast()?)),
                PropInfo::DESCRIPTION => Ok(ObjectPropInfoType::DESCRIPTION(value.pod().cast()?)),
                _ => Err(PodError::UnknownPodTypeToDowncast),
            }
        }
    }
}

enum_wrapper!(
    PropInfo,
    spa_sys::spa_prop_info,
    _START: spa_sys::SPA_PROP_INFO_START,
    ID: spa_sys::SPA_PROP_INFO_id,
    NAME: spa_sys::SPA_PROP_INFO_name,
    TYPE: spa_sys::SPA_PROP_INFO_type,
    LABELS: spa_sys::SPA_PROP_INFO_labels,
    CONTAINER: spa_sys::SPA_PROP_INFO_container,
    PARAMS: spa_sys::SPA_PROP_INFO_params,
    DESCRIPTION: spa_sys::SPA_PROP_INFO_description,
);