mod abort_function_call;
mod add_bus_listener_filter;
mod add_channel_capacity;
mod bus_listener_current_finished;
mod call_function;
mod call_function2;
mod call_function_reply;
mod channel_end_claimed;
mod channel_end_closed;
mod claim_channel_end;
mod claim_channel_end_reply;
mod clear_bus_listener_filters;
mod close_channel_end;
mod close_channel_end_reply;
mod connect;
mod connect2;
mod connect_reply;
mod connect_reply2;
mod create_bus_listener;
mod create_bus_listener_reply;
mod create_channel;
mod create_channel_reply;
mod create_object;
mod create_object_reply;
mod create_service;
mod create_service2;
mod create_service_reply;
mod deserializer;
mod destroy_bus_listener;
mod destroy_bus_listener_reply;
mod destroy_object;
mod destroy_object_reply;
mod destroy_service;
mod destroy_service_reply;
mod emit_bus_event;
mod emit_event;
mod error;
mod item_received;
mod kind;
mod packetizer;
mod query_introspection;
mod query_introspection_reply;
mod query_service_info;
mod query_service_info_reply;
mod query_service_version;
mod query_service_version_reply;
mod register_introspection;
mod remove_bus_listener_filter;
mod send_item;
mod serializer;
mod service_destroyed;
mod shutdown;
mod start_bus_listener;
mod start_bus_listener_reply;
mod stop_bus_listener;
mod stop_bus_listener_reply;
mod subscribe_all_events;
mod subscribe_all_events_reply;
mod subscribe_event;
mod subscribe_event_reply;
mod subscribe_service;
mod subscribe_service_reply;
mod sync;
mod sync_reply;
#[cfg(test)]
mod test;
mod unsubscribe_all_events;
mod unsubscribe_all_events_reply;
mod unsubscribe_event;
mod unsubscribe_service;

use crate::{
    convert_value, ProtocolVersion, SerializedValue, SerializedValueSlice, ValueConversionError,
};
use bytes::BytesMut;
use num_enum::{IntoPrimitive, TryFromPrimitive};

pub(crate) use deserializer::{MessageWithValueDeserializer, MessageWithoutValueDeserializer};
pub(crate) use serializer::MessageSerializer;

pub use abort_function_call::AbortFunctionCall;
pub use add_bus_listener_filter::AddBusListenerFilter;
pub use add_channel_capacity::AddChannelCapacity;
pub use bus_listener_current_finished::BusListenerCurrentFinished;
pub use call_function::CallFunction;
pub use call_function2::CallFunction2;
pub use call_function_reply::{CallFunctionReply, CallFunctionResult};
pub use channel_end_claimed::ChannelEndClaimed;
pub use channel_end_closed::ChannelEndClosed;
pub use claim_channel_end::ClaimChannelEnd;
pub use claim_channel_end_reply::{ClaimChannelEndReply, ClaimChannelEndResult};
pub use clear_bus_listener_filters::ClearBusListenerFilters;
pub use close_channel_end::CloseChannelEnd;
pub use close_channel_end_reply::{CloseChannelEndReply, CloseChannelEndResult};
pub use connect::Connect;
pub use connect2::{Connect2, ConnectData};
pub use connect_reply::ConnectReply;
pub use connect_reply2::{ConnectReply2, ConnectReplyData, ConnectResult};
pub use create_bus_listener::CreateBusListener;
pub use create_bus_listener_reply::CreateBusListenerReply;
pub use create_channel::CreateChannel;
pub use create_channel_reply::CreateChannelReply;
pub use create_object::CreateObject;
pub use create_object_reply::{CreateObjectReply, CreateObjectResult};
pub use create_service::CreateService;
pub use create_service2::CreateService2;
pub use create_service_reply::{CreateServiceReply, CreateServiceResult};
pub use destroy_bus_listener::DestroyBusListener;
pub use destroy_bus_listener_reply::{DestroyBusListenerReply, DestroyBusListenerResult};
pub use destroy_object::DestroyObject;
pub use destroy_object_reply::{DestroyObjectReply, DestroyObjectResult};
pub use destroy_service::DestroyService;
pub use destroy_service_reply::{DestroyServiceReply, DestroyServiceResult};
pub use emit_bus_event::EmitBusEvent;
pub use emit_event::EmitEvent;
pub use error::{MessageDeserializeError, MessageSerializeError};
pub use item_received::ItemReceived;
pub use kind::MessageKind;
pub use packetizer::Packetizer;
pub use query_introspection::QueryIntrospection;
pub use query_introspection_reply::{QueryIntrospectionReply, QueryIntrospectionResult};
pub use query_service_info::QueryServiceInfo;
pub use query_service_info_reply::{QueryServiceInfoReply, QueryServiceInfoResult};
pub use query_service_version::QueryServiceVersion;
pub use query_service_version_reply::{QueryServiceVersionReply, QueryServiceVersionResult};
pub use register_introspection::RegisterIntrospection;
pub use remove_bus_listener_filter::RemoveBusListenerFilter;
pub use send_item::SendItem;
pub use service_destroyed::ServiceDestroyed;
pub use shutdown::Shutdown;
pub use start_bus_listener::StartBusListener;
pub use start_bus_listener_reply::{StartBusListenerReply, StartBusListenerResult};
pub use stop_bus_listener::StopBusListener;
pub use stop_bus_listener_reply::{StopBusListenerReply, StopBusListenerResult};
pub use subscribe_all_events::SubscribeAllEvents;
pub use subscribe_all_events_reply::{SubscribeAllEventsReply, SubscribeAllEventsResult};
pub use subscribe_event::SubscribeEvent;
pub use subscribe_event_reply::{SubscribeEventReply, SubscribeEventResult};
pub use subscribe_service::SubscribeService;
pub use subscribe_service_reply::{SubscribeServiceReply, SubscribeServiceResult};
pub use sync::Sync;
pub use sync_reply::SyncReply;
pub use unsubscribe_all_events::UnsubscribeAllEvents;
pub use unsubscribe_all_events_reply::{UnsubscribeAllEventsReply, UnsubscribeAllEventsResult};
pub use unsubscribe_event::UnsubscribeEvent;
pub use unsubscribe_service::UnsubscribeService;

mod message_ops {
    #[allow(unnameable_types)]
    pub trait Sealed {}
}

pub trait MessageOps: Sized + message_ops::Sealed {
    fn kind(&self) -> MessageKind;
    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError>;
    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError>;
    fn value(&self) -> Option<&SerializedValueSlice>;
    fn value_mut(&mut self) -> Option<&mut SerializedValue>;

    fn convert_value(
        &mut self,
        from: Option<ProtocolVersion>,
        to: ProtocolVersion,
    ) -> Result<(), ValueConversionError> {
        convert_value::convert_in_message(self, from, to)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
pub enum Message {
    Connect(Connect),
    ConnectReply(ConnectReply),
    Shutdown(Shutdown),
    CreateObject(CreateObject),
    CreateObjectReply(CreateObjectReply),
    DestroyObject(DestroyObject),
    DestroyObjectReply(DestroyObjectReply),
    CreateService(CreateService),
    CreateServiceReply(CreateServiceReply),
    DestroyService(DestroyService),
    DestroyServiceReply(DestroyServiceReply),
    CallFunction(CallFunction),
    CallFunctionReply(CallFunctionReply),
    SubscribeEvent(SubscribeEvent),
    SubscribeEventReply(SubscribeEventReply),
    UnsubscribeEvent(UnsubscribeEvent),
    EmitEvent(EmitEvent),
    QueryServiceVersion(QueryServiceVersion),
    QueryServiceVersionReply(QueryServiceVersionReply),
    CreateChannel(CreateChannel),
    CreateChannelReply(CreateChannelReply),
    CloseChannelEnd(CloseChannelEnd),
    CloseChannelEndReply(CloseChannelEndReply),
    ChannelEndClosed(ChannelEndClosed),
    ClaimChannelEnd(ClaimChannelEnd),
    ClaimChannelEndReply(ClaimChannelEndReply),
    ChannelEndClaimed(ChannelEndClaimed),
    SendItem(SendItem),
    ItemReceived(ItemReceived),
    AddChannelCapacity(AddChannelCapacity),
    Sync(Sync),
    SyncReply(SyncReply),
    ServiceDestroyed(ServiceDestroyed),
    CreateBusListener(CreateBusListener),
    CreateBusListenerReply(CreateBusListenerReply),
    DestroyBusListener(DestroyBusListener),
    DestroyBusListenerReply(DestroyBusListenerReply),
    AddBusListenerFilter(AddBusListenerFilter),
    RemoveBusListenerFilter(RemoveBusListenerFilter),
    ClearBusListenerFilters(ClearBusListenerFilters),
    StartBusListener(StartBusListener),
    StartBusListenerReply(StartBusListenerReply),
    StopBusListener(StopBusListener),
    StopBusListenerReply(StopBusListenerReply),
    EmitBusEvent(EmitBusEvent),
    BusListenerCurrentFinished(BusListenerCurrentFinished),
    Connect2(Connect2),
    ConnectReply2(ConnectReply2),
    AbortFunctionCall(AbortFunctionCall),
    RegisterIntrospection(RegisterIntrospection),
    QueryIntrospection(QueryIntrospection),
    QueryIntrospectionReply(QueryIntrospectionReply),
    CreateService2(CreateService2),
    QueryServiceInfo(QueryServiceInfo),
    QueryServiceInfoReply(QueryServiceInfoReply),
    SubscribeService(SubscribeService),
    SubscribeServiceReply(SubscribeServiceReply),
    UnsubscribeService(UnsubscribeService),
    SubscribeAllEvents(SubscribeAllEvents),
    SubscribeAllEventsReply(SubscribeAllEventsReply),
    UnsubscribeAllEvents(UnsubscribeAllEvents),
    UnsubscribeAllEventsReply(UnsubscribeAllEventsReply),
    CallFunction2(CallFunction2),
}

impl MessageOps for Message {
    fn kind(&self) -> MessageKind {
        match self {
            Self::Connect(_) => MessageKind::Connect,
            Self::ConnectReply(_) => MessageKind::ConnectReply,
            Self::Shutdown(_) => MessageKind::Shutdown,
            Self::CreateObject(_) => MessageKind::CreateObject,
            Self::CreateObjectReply(_) => MessageKind::CreateObjectReply,
            Self::DestroyObject(_) => MessageKind::DestroyObject,
            Self::DestroyObjectReply(_) => MessageKind::DestroyObjectReply,
            Self::CreateService(_) => MessageKind::CreateService,
            Self::CreateServiceReply(_) => MessageKind::CreateServiceReply,
            Self::DestroyService(_) => MessageKind::DestroyService,
            Self::DestroyServiceReply(_) => MessageKind::DestroyServiceReply,
            Self::CallFunction(_) => MessageKind::CallFunction,
            Self::CallFunctionReply(_) => MessageKind::CallFunctionReply,
            Self::SubscribeEvent(_) => MessageKind::SubscribeEvent,
            Self::SubscribeEventReply(_) => MessageKind::SubscribeEventReply,
            Self::UnsubscribeEvent(_) => MessageKind::UnsubscribeEvent,
            Self::EmitEvent(_) => MessageKind::EmitEvent,
            Self::QueryServiceVersion(_) => MessageKind::QueryServiceVersion,
            Self::QueryServiceVersionReply(_) => MessageKind::QueryServiceVersionReply,
            Self::CreateChannel(_) => MessageKind::CreateChannel,
            Self::CreateChannelReply(_) => MessageKind::CreateChannelReply,
            Self::CloseChannelEnd(_) => MessageKind::CloseChannelEnd,
            Self::CloseChannelEndReply(_) => MessageKind::CloseChannelEndReply,
            Self::ChannelEndClosed(_) => MessageKind::ChannelEndClosed,
            Self::ClaimChannelEnd(_) => MessageKind::ClaimChannelEnd,
            Self::ClaimChannelEndReply(_) => MessageKind::ClaimChannelEndReply,
            Self::ChannelEndClaimed(_) => MessageKind::ChannelEndClaimed,
            Self::SendItem(_) => MessageKind::SendItem,
            Self::ItemReceived(_) => MessageKind::ItemReceived,
            Self::AddChannelCapacity(_) => MessageKind::AddChannelCapacity,
            Self::Sync(_) => MessageKind::Sync,
            Self::SyncReply(_) => MessageKind::SyncReply,
            Self::ServiceDestroyed(_) => MessageKind::ServiceDestroyed,
            Self::CreateBusListener(_) => MessageKind::CreateBusListener,
            Self::CreateBusListenerReply(_) => MessageKind::CreateBusListenerReply,
            Self::DestroyBusListener(_) => MessageKind::DestroyBusListener,
            Self::DestroyBusListenerReply(_) => MessageKind::DestroyBusListenerReply,
            Self::AddBusListenerFilter(_) => MessageKind::AddBusListenerFilter,
            Self::RemoveBusListenerFilter(_) => MessageKind::RemoveBusListenerFilter,
            Self::ClearBusListenerFilters(_) => MessageKind::ClearBusListenerFilters,
            Self::StartBusListener(_) => MessageKind::StartBusListener,
            Self::StartBusListenerReply(_) => MessageKind::StartBusListenerReply,
            Self::StopBusListener(_) => MessageKind::StopBusListener,
            Self::StopBusListenerReply(_) => MessageKind::StopBusListenerReply,
            Self::EmitBusEvent(_) => MessageKind::EmitBusEvent,
            Self::BusListenerCurrentFinished(_) => MessageKind::BusListenerCurrentFinished,
            Self::Connect2(_) => MessageKind::Connect2,
            Self::ConnectReply2(_) => MessageKind::ConnectReply2,
            Self::AbortFunctionCall(_) => MessageKind::AbortFunctionCall,
            Self::RegisterIntrospection(_) => MessageKind::RegisterIntrospection,
            Self::QueryIntrospection(_) => MessageKind::QueryIntrospection,
            Self::QueryIntrospectionReply(_) => MessageKind::QueryIntrospectionReply,
            Self::CreateService2(_) => MessageKind::CreateService2,
            Self::QueryServiceInfo(_) => MessageKind::QueryServiceInfo,
            Self::QueryServiceInfoReply(_) => MessageKind::QueryServiceInfoReply,
            Self::SubscribeService(_) => MessageKind::SubscribeService,
            Self::SubscribeServiceReply(_) => MessageKind::SubscribeServiceReply,
            Self::UnsubscribeService(_) => MessageKind::UnsubscribeService,
            Self::SubscribeAllEvents(_) => MessageKind::SubscribeAllEvents,
            Self::SubscribeAllEventsReply(_) => MessageKind::SubscribeAllEventsReply,
            Self::UnsubscribeAllEvents(_) => MessageKind::UnsubscribeAllEvents,
            Self::UnsubscribeAllEventsReply(_) => MessageKind::UnsubscribeAllEventsReply,
            Self::CallFunction2(_) => MessageKind::CallFunction2,
        }
    }

    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
        match self {
            Self::Connect(msg) => msg.serialize_message(),
            Self::ConnectReply(msg) => msg.serialize_message(),
            Self::Shutdown(msg) => msg.serialize_message(),
            Self::CreateObject(msg) => msg.serialize_message(),
            Self::CreateObjectReply(msg) => msg.serialize_message(),
            Self::DestroyObject(msg) => msg.serialize_message(),
            Self::DestroyObjectReply(msg) => msg.serialize_message(),
            Self::CreateService(msg) => msg.serialize_message(),
            Self::CreateServiceReply(msg) => msg.serialize_message(),
            Self::DestroyService(msg) => msg.serialize_message(),
            Self::DestroyServiceReply(msg) => msg.serialize_message(),
            Self::CallFunction(msg) => msg.serialize_message(),
            Self::CallFunctionReply(msg) => msg.serialize_message(),
            Self::SubscribeEvent(msg) => msg.serialize_message(),
            Self::SubscribeEventReply(msg) => msg.serialize_message(),
            Self::UnsubscribeEvent(msg) => msg.serialize_message(),
            Self::EmitEvent(msg) => msg.serialize_message(),
            Self::QueryServiceVersion(msg) => msg.serialize_message(),
            Self::QueryServiceVersionReply(msg) => msg.serialize_message(),
            Self::CreateChannel(msg) => msg.serialize_message(),
            Self::CreateChannelReply(msg) => msg.serialize_message(),
            Self::CloseChannelEnd(msg) => msg.serialize_message(),
            Self::CloseChannelEndReply(msg) => msg.serialize_message(),
            Self::ChannelEndClosed(msg) => msg.serialize_message(),
            Self::ClaimChannelEnd(msg) => msg.serialize_message(),
            Self::ClaimChannelEndReply(msg) => msg.serialize_message(),
            Self::ChannelEndClaimed(msg) => msg.serialize_message(),
            Self::SendItem(msg) => msg.serialize_message(),
            Self::ItemReceived(msg) => msg.serialize_message(),
            Self::AddChannelCapacity(msg) => msg.serialize_message(),
            Self::Sync(msg) => msg.serialize_message(),
            Self::SyncReply(msg) => msg.serialize_message(),
            Self::ServiceDestroyed(msg) => msg.serialize_message(),
            Self::CreateBusListener(msg) => msg.serialize_message(),
            Self::CreateBusListenerReply(msg) => msg.serialize_message(),
            Self::DestroyBusListener(msg) => msg.serialize_message(),
            Self::DestroyBusListenerReply(msg) => msg.serialize_message(),
            Self::AddBusListenerFilter(msg) => msg.serialize_message(),
            Self::RemoveBusListenerFilter(msg) => msg.serialize_message(),
            Self::ClearBusListenerFilters(msg) => msg.serialize_message(),
            Self::StartBusListener(msg) => msg.serialize_message(),
            Self::StartBusListenerReply(msg) => msg.serialize_message(),
            Self::StopBusListener(msg) => msg.serialize_message(),
            Self::StopBusListenerReply(msg) => msg.serialize_message(),
            Self::EmitBusEvent(msg) => msg.serialize_message(),
            Self::BusListenerCurrentFinished(msg) => msg.serialize_message(),
            Self::Connect2(msg) => msg.serialize_message(),
            Self::ConnectReply2(msg) => msg.serialize_message(),
            Self::AbortFunctionCall(msg) => msg.serialize_message(),
            Self::RegisterIntrospection(msg) => msg.serialize_message(),
            Self::QueryIntrospection(msg) => msg.serialize_message(),
            Self::QueryIntrospectionReply(msg) => msg.serialize_message(),
            Self::CreateService2(msg) => msg.serialize_message(),
            Self::QueryServiceInfo(msg) => msg.serialize_message(),
            Self::QueryServiceInfoReply(msg) => msg.serialize_message(),
            Self::SubscribeService(msg) => msg.serialize_message(),
            Self::SubscribeServiceReply(msg) => msg.serialize_message(),
            Self::UnsubscribeService(msg) => msg.serialize_message(),
            Self::SubscribeAllEvents(msg) => msg.serialize_message(),
            Self::SubscribeAllEventsReply(msg) => msg.serialize_message(),
            Self::UnsubscribeAllEvents(msg) => msg.serialize_message(),
            Self::UnsubscribeAllEventsReply(msg) => msg.serialize_message(),
            Self::CallFunction2(msg) => msg.serialize_message(),
        }
    }

    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
        if buf.len() < 5 {
            return Err(MessageDeserializeError::UnexpectedEoi);
        }

        let kind = buf[4]
            .try_into()
            .map_err(|_| MessageDeserializeError::InvalidSerialization)?;

        match kind {
            MessageKind::Connect => Connect::deserialize_message(buf).map(Self::Connect),

            MessageKind::ConnectReply => {
                ConnectReply::deserialize_message(buf).map(Self::ConnectReply)
            }

            MessageKind::Shutdown => Shutdown::deserialize_message(buf).map(Self::Shutdown),

            MessageKind::CreateObject => {
                CreateObject::deserialize_message(buf).map(Self::CreateObject)
            }

            MessageKind::CreateObjectReply => {
                CreateObjectReply::deserialize_message(buf).map(Self::CreateObjectReply)
            }

            MessageKind::DestroyObject => {
                DestroyObject::deserialize_message(buf).map(Self::DestroyObject)
            }

            MessageKind::DestroyObjectReply => {
                DestroyObjectReply::deserialize_message(buf).map(Self::DestroyObjectReply)
            }

            MessageKind::CreateService => {
                CreateService::deserialize_message(buf).map(Self::CreateService)
            }

            MessageKind::CreateServiceReply => {
                CreateServiceReply::deserialize_message(buf).map(Self::CreateServiceReply)
            }

            MessageKind::DestroyService => {
                DestroyService::deserialize_message(buf).map(Self::DestroyService)
            }

            MessageKind::DestroyServiceReply => {
                DestroyServiceReply::deserialize_message(buf).map(Self::DestroyServiceReply)
            }

            MessageKind::CallFunction => {
                CallFunction::deserialize_message(buf).map(Self::CallFunction)
            }

            MessageKind::CallFunctionReply => {
                CallFunctionReply::deserialize_message(buf).map(Self::CallFunctionReply)
            }

            MessageKind::SubscribeEvent => {
                SubscribeEvent::deserialize_message(buf).map(Self::SubscribeEvent)
            }

            MessageKind::SubscribeEventReply => {
                SubscribeEventReply::deserialize_message(buf).map(Self::SubscribeEventReply)
            }

            MessageKind::UnsubscribeEvent => {
                UnsubscribeEvent::deserialize_message(buf).map(Self::UnsubscribeEvent)
            }

            MessageKind::EmitEvent => EmitEvent::deserialize_message(buf).map(Self::EmitEvent),

            MessageKind::QueryServiceVersion => {
                QueryServiceVersion::deserialize_message(buf).map(Self::QueryServiceVersion)
            }

            MessageKind::QueryServiceVersionReply => {
                QueryServiceVersionReply::deserialize_message(buf)
                    .map(Self::QueryServiceVersionReply)
            }

            MessageKind::CreateChannel => {
                CreateChannel::deserialize_message(buf).map(Self::CreateChannel)
            }

            MessageKind::CreateChannelReply => {
                CreateChannelReply::deserialize_message(buf).map(Self::CreateChannelReply)
            }

            MessageKind::CloseChannelEnd => {
                CloseChannelEnd::deserialize_message(buf).map(Self::CloseChannelEnd)
            }

            MessageKind::CloseChannelEndReply => {
                CloseChannelEndReply::deserialize_message(buf).map(Self::CloseChannelEndReply)
            }

            MessageKind::ChannelEndClosed => {
                ChannelEndClosed::deserialize_message(buf).map(Self::ChannelEndClosed)
            }

            MessageKind::ClaimChannelEnd => {
                ClaimChannelEnd::deserialize_message(buf).map(Self::ClaimChannelEnd)
            }

            MessageKind::ClaimChannelEndReply => {
                ClaimChannelEndReply::deserialize_message(buf).map(Self::ClaimChannelEndReply)
            }

            MessageKind::ChannelEndClaimed => {
                ChannelEndClaimed::deserialize_message(buf).map(Self::ChannelEndClaimed)
            }

            MessageKind::SendItem => SendItem::deserialize_message(buf).map(Self::SendItem),

            MessageKind::ItemReceived => {
                ItemReceived::deserialize_message(buf).map(Self::ItemReceived)
            }

            MessageKind::AddChannelCapacity => {
                AddChannelCapacity::deserialize_message(buf).map(Self::AddChannelCapacity)
            }

            MessageKind::Sync => Sync::deserialize_message(buf).map(Self::Sync),
            MessageKind::SyncReply => SyncReply::deserialize_message(buf).map(Self::SyncReply),

            MessageKind::ServiceDestroyed => {
                ServiceDestroyed::deserialize_message(buf).map(Self::ServiceDestroyed)
            }

            MessageKind::CreateBusListener => {
                CreateBusListener::deserialize_message(buf).map(Self::CreateBusListener)
            }

            MessageKind::CreateBusListenerReply => {
                CreateBusListenerReply::deserialize_message(buf).map(Self::CreateBusListenerReply)
            }

            MessageKind::DestroyBusListener => {
                DestroyBusListener::deserialize_message(buf).map(Self::DestroyBusListener)
            }

            MessageKind::DestroyBusListenerReply => {
                DestroyBusListenerReply::deserialize_message(buf).map(Self::DestroyBusListenerReply)
            }

            MessageKind::AddBusListenerFilter => {
                AddBusListenerFilter::deserialize_message(buf).map(Self::AddBusListenerFilter)
            }

            MessageKind::RemoveBusListenerFilter => {
                RemoveBusListenerFilter::deserialize_message(buf).map(Self::RemoveBusListenerFilter)
            }

            MessageKind::ClearBusListenerFilters => {
                ClearBusListenerFilters::deserialize_message(buf).map(Self::ClearBusListenerFilters)
            }

            MessageKind::StartBusListener => {
                StartBusListener::deserialize_message(buf).map(Self::StartBusListener)
            }

            MessageKind::StartBusListenerReply => {
                StartBusListenerReply::deserialize_message(buf).map(Self::StartBusListenerReply)
            }

            MessageKind::StopBusListener => {
                StopBusListener::deserialize_message(buf).map(Self::StopBusListener)
            }

            MessageKind::StopBusListenerReply => {
                StopBusListenerReply::deserialize_message(buf).map(Self::StopBusListenerReply)
            }

            MessageKind::EmitBusEvent => {
                EmitBusEvent::deserialize_message(buf).map(Self::EmitBusEvent)
            }

            MessageKind::BusListenerCurrentFinished => {
                BusListenerCurrentFinished::deserialize_message(buf)
                    .map(Self::BusListenerCurrentFinished)
            }

            MessageKind::Connect2 => Connect2::deserialize_message(buf).map(Self::Connect2),

            MessageKind::ConnectReply2 => {
                ConnectReply2::deserialize_message(buf).map(Self::ConnectReply2)
            }

            MessageKind::AbortFunctionCall => {
                AbortFunctionCall::deserialize_message(buf).map(Self::AbortFunctionCall)
            }

            MessageKind::RegisterIntrospection => {
                RegisterIntrospection::deserialize_message(buf).map(Self::RegisterIntrospection)
            }

            MessageKind::QueryIntrospection => {
                QueryIntrospection::deserialize_message(buf).map(Self::QueryIntrospection)
            }

            MessageKind::QueryIntrospectionReply => {
                QueryIntrospectionReply::deserialize_message(buf).map(Self::QueryIntrospectionReply)
            }

            MessageKind::CreateService2 => {
                CreateService2::deserialize_message(buf).map(Self::CreateService2)
            }

            MessageKind::QueryServiceInfo => {
                QueryServiceInfo::deserialize_message(buf).map(Self::QueryServiceInfo)
            }

            MessageKind::QueryServiceInfoReply => {
                QueryServiceInfoReply::deserialize_message(buf).map(Self::QueryServiceInfoReply)
            }

            MessageKind::SubscribeService => {
                SubscribeService::deserialize_message(buf).map(Self::SubscribeService)
            }

            MessageKind::SubscribeServiceReply => {
                SubscribeServiceReply::deserialize_message(buf).map(Self::SubscribeServiceReply)
            }

            MessageKind::UnsubscribeService => {
                UnsubscribeService::deserialize_message(buf).map(Self::UnsubscribeService)
            }

            MessageKind::SubscribeAllEvents => {
                SubscribeAllEvents::deserialize_message(buf).map(Self::SubscribeAllEvents)
            }

            MessageKind::SubscribeAllEventsReply => {
                SubscribeAllEventsReply::deserialize_message(buf).map(Self::SubscribeAllEventsReply)
            }

            MessageKind::UnsubscribeAllEvents => {
                UnsubscribeAllEvents::deserialize_message(buf).map(Self::UnsubscribeAllEvents)
            }

            MessageKind::UnsubscribeAllEventsReply => {
                UnsubscribeAllEventsReply::deserialize_message(buf)
                    .map(Self::UnsubscribeAllEventsReply)
            }

            MessageKind::CallFunction2 => {
                CallFunction2::deserialize_message(buf).map(Self::CallFunction2)
            }
        }
    }

    fn value(&self) -> Option<&SerializedValueSlice> {
        match self {
            Self::Connect(msg) => msg.value(),
            Self::ConnectReply(msg) => msg.value(),
            Self::Shutdown(msg) => msg.value(),
            Self::CreateObject(msg) => msg.value(),
            Self::CreateObjectReply(msg) => msg.value(),
            Self::DestroyObject(msg) => msg.value(),
            Self::DestroyObjectReply(msg) => msg.value(),
            Self::CreateService(msg) => msg.value(),
            Self::CreateServiceReply(msg) => msg.value(),
            Self::DestroyService(msg) => msg.value(),
            Self::DestroyServiceReply(msg) => msg.value(),
            Self::CallFunction(msg) => msg.value(),
            Self::CallFunctionReply(msg) => msg.value(),
            Self::SubscribeEvent(msg) => msg.value(),
            Self::SubscribeEventReply(msg) => msg.value(),
            Self::UnsubscribeEvent(msg) => msg.value(),
            Self::EmitEvent(msg) => msg.value(),
            Self::QueryServiceVersion(msg) => msg.value(),
            Self::QueryServiceVersionReply(msg) => msg.value(),
            Self::CreateChannel(msg) => msg.value(),
            Self::CreateChannelReply(msg) => msg.value(),
            Self::CloseChannelEnd(msg) => msg.value(),
            Self::CloseChannelEndReply(msg) => msg.value(),
            Self::ChannelEndClosed(msg) => msg.value(),
            Self::ClaimChannelEnd(msg) => msg.value(),
            Self::ClaimChannelEndReply(msg) => msg.value(),
            Self::ChannelEndClaimed(msg) => msg.value(),
            Self::SendItem(msg) => msg.value(),
            Self::ItemReceived(msg) => msg.value(),
            Self::AddChannelCapacity(msg) => msg.value(),
            Self::Sync(msg) => msg.value(),
            Self::SyncReply(msg) => msg.value(),
            Self::ServiceDestroyed(msg) => msg.value(),
            Self::CreateBusListener(msg) => msg.value(),
            Self::CreateBusListenerReply(msg) => msg.value(),
            Self::DestroyBusListener(msg) => msg.value(),
            Self::DestroyBusListenerReply(msg) => msg.value(),
            Self::AddBusListenerFilter(msg) => msg.value(),
            Self::RemoveBusListenerFilter(msg) => msg.value(),
            Self::ClearBusListenerFilters(msg) => msg.value(),
            Self::StartBusListener(msg) => msg.value(),
            Self::StartBusListenerReply(msg) => msg.value(),
            Self::StopBusListener(msg) => msg.value(),
            Self::StopBusListenerReply(msg) => msg.value(),
            Self::EmitBusEvent(msg) => msg.value(),
            Self::BusListenerCurrentFinished(msg) => msg.value(),
            Self::Connect2(msg) => msg.value(),
            Self::ConnectReply2(msg) => msg.value(),
            Self::AbortFunctionCall(msg) => msg.value(),
            Self::RegisterIntrospection(msg) => msg.value(),
            Self::QueryIntrospection(msg) => msg.value(),
            Self::QueryIntrospectionReply(msg) => msg.value(),
            Self::CreateService2(msg) => msg.value(),
            Self::QueryServiceInfo(msg) => msg.value(),
            Self::QueryServiceInfoReply(msg) => msg.value(),
            Self::SubscribeService(msg) => msg.value(),
            Self::SubscribeServiceReply(msg) => msg.value(),
            Self::UnsubscribeService(msg) => msg.value(),
            Self::SubscribeAllEvents(msg) => msg.value(),
            Self::SubscribeAllEventsReply(msg) => msg.value(),
            Self::UnsubscribeAllEvents(msg) => msg.value(),
            Self::UnsubscribeAllEventsReply(msg) => msg.value(),
            Self::CallFunction2(msg) => msg.value(),
        }
    }
    fn value_mut(&mut self) -> Option<&mut SerializedValue> {
        match self {
            Self::Connect(msg) => msg.value_mut(),
            Self::ConnectReply(msg) => msg.value_mut(),
            Self::Shutdown(msg) => msg.value_mut(),
            Self::CreateObject(msg) => msg.value_mut(),
            Self::CreateObjectReply(msg) => msg.value_mut(),
            Self::DestroyObject(msg) => msg.value_mut(),
            Self::DestroyObjectReply(msg) => msg.value_mut(),
            Self::CreateService(msg) => msg.value_mut(),
            Self::CreateServiceReply(msg) => msg.value_mut(),
            Self::DestroyService(msg) => msg.value_mut(),
            Self::DestroyServiceReply(msg) => msg.value_mut(),
            Self::CallFunction(msg) => msg.value_mut(),
            Self::CallFunctionReply(msg) => msg.value_mut(),
            Self::SubscribeEvent(msg) => msg.value_mut(),
            Self::SubscribeEventReply(msg) => msg.value_mut(),
            Self::UnsubscribeEvent(msg) => msg.value_mut(),
            Self::EmitEvent(msg) => msg.value_mut(),
            Self::QueryServiceVersion(msg) => msg.value_mut(),
            Self::QueryServiceVersionReply(msg) => msg.value_mut(),
            Self::CreateChannel(msg) => msg.value_mut(),
            Self::CreateChannelReply(msg) => msg.value_mut(),
            Self::CloseChannelEnd(msg) => msg.value_mut(),
            Self::CloseChannelEndReply(msg) => msg.value_mut(),
            Self::ChannelEndClosed(msg) => msg.value_mut(),
            Self::ClaimChannelEnd(msg) => msg.value_mut(),
            Self::ClaimChannelEndReply(msg) => msg.value_mut(),
            Self::ChannelEndClaimed(msg) => msg.value_mut(),
            Self::SendItem(msg) => msg.value_mut(),
            Self::ItemReceived(msg) => msg.value_mut(),
            Self::AddChannelCapacity(msg) => msg.value_mut(),
            Self::Sync(msg) => msg.value_mut(),
            Self::SyncReply(msg) => msg.value_mut(),
            Self::ServiceDestroyed(msg) => msg.value_mut(),
            Self::CreateBusListener(msg) => msg.value_mut(),
            Self::CreateBusListenerReply(msg) => msg.value_mut(),
            Self::DestroyBusListener(msg) => msg.value_mut(),
            Self::DestroyBusListenerReply(msg) => msg.value_mut(),
            Self::AddBusListenerFilter(msg) => msg.value_mut(),
            Self::RemoveBusListenerFilter(msg) => msg.value_mut(),
            Self::ClearBusListenerFilters(msg) => msg.value_mut(),
            Self::StartBusListener(msg) => msg.value_mut(),
            Self::StartBusListenerReply(msg) => msg.value_mut(),
            Self::StopBusListener(msg) => msg.value_mut(),
            Self::StopBusListenerReply(msg) => msg.value_mut(),
            Self::EmitBusEvent(msg) => msg.value_mut(),
            Self::BusListenerCurrentFinished(msg) => msg.value_mut(),
            Self::Connect2(msg) => msg.value_mut(),
            Self::ConnectReply2(msg) => msg.value_mut(),
            Self::AbortFunctionCall(msg) => msg.value_mut(),
            Self::RegisterIntrospection(msg) => msg.value_mut(),
            Self::QueryIntrospection(msg) => msg.value_mut(),
            Self::QueryIntrospectionReply(msg) => msg.value_mut(),
            Self::CreateService2(msg) => msg.value_mut(),
            Self::QueryServiceInfo(msg) => msg.value_mut(),
            Self::QueryServiceInfoReply(msg) => msg.value_mut(),
            Self::SubscribeService(msg) => msg.value_mut(),
            Self::SubscribeServiceReply(msg) => msg.value_mut(),
            Self::UnsubscribeService(msg) => msg.value_mut(),
            Self::SubscribeAllEvents(msg) => msg.value_mut(),
            Self::SubscribeAllEventsReply(msg) => msg.value_mut(),
            Self::UnsubscribeAllEvents(msg) => msg.value_mut(),
            Self::UnsubscribeAllEventsReply(msg) => msg.value_mut(),
            Self::CallFunction2(msg) => msg.value_mut(),
        }
    }
}

impl message_ops::Sealed for Message {}

#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
enum OptionKind {
    None = 0,
    Some = 1,
}
