atri_plugin 0.9.0

AtriPlugin
Documentation
use crate::message::MessageChain;

#[derive(Default, Clone)]
pub struct ForwardMessage(Vec<ForwardNode>);

impl ForwardMessage {
    pub fn new() -> Self {
        Self(vec![])
    }

    pub fn with_capacity(capacity: usize) -> Self {
        Self(Vec::with_capacity(capacity))
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn iter(&self) -> std::slice::Iter<ForwardNode> {
        self.0.iter()
    }

    pub fn push(&mut self, node: ForwardNode) {
        self.0.push(node);
    }

    pub fn push_node<I: IntoForwardNode>(&mut self, info: ForwardNodeInfo, node: I) {
        self.push(node.into_node(info))
    }

    pub fn push_message<M: Into<MessageChain>>(&mut self, info: ForwardNodeInfo, msg: M) {
        self.push(ForwardNode::NormalMessage {
            info,
            chain: msg.into(),
        })
    }

    pub fn push_forward<M: Into<ForwardMessage>>(&mut self, info: ForwardNodeInfo, msg: M) {
        self.push(ForwardNode::ForwardMessage {
            info,
            forward: msg.into(),
        })
    }
}

pub trait IntoForwardNode {
    fn into_node(self, info: ForwardNodeInfo) -> ForwardNode;
}

impl IntoForwardNode for MessageChain {
    fn into_node(self, info: ForwardNodeInfo) -> ForwardNode {
        ForwardNode::NormalMessage { info, chain: self }
    }
}

impl IntoForwardNode for ForwardMessage {
    fn into_node(self, info: ForwardNodeInfo) -> ForwardNode {
        ForwardNode::ForwardMessage {
            info,
            forward: self,
        }
    }
}

impl IntoForwardNode for ForwardNode {
    fn into_node(self, _: ForwardNodeInfo) -> ForwardNode {
        self
    }
}

impl IntoIterator for ForwardMessage {
    type Item = ForwardNode;
    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

#[derive(Clone)]
pub enum ForwardNode {
    NormalMessage {
        info: ForwardNodeInfo,
        chain: MessageChain,
    },
    ForwardMessage {
        info: ForwardNodeInfo,
        forward: ForwardMessage,
    },
}

#[derive(Default, Debug, Clone)]
pub struct ForwardNodeInfo {
    pub sender_id: i64,
    pub sender_name: String,
    pub time: i32,
}

mod ffi {
    use super::{ForwardMessage, ForwardNode, ForwardNodeInfo};
    use crate::message::MessageChain;
    use atri_ffi::ffi::ForFFI;
    use atri_ffi::message::forward::{FFIForwardNode, FFIForwardNodeInfo, ForwardNodeUnion};
    use atri_ffi::RustVec;
    use std::mem::ManuallyDrop;

    impl ForFFI for ForwardNode {
        type FFIValue = FFIForwardNode;

        fn into_ffi(self) -> Self::FFIValue {
            match self {
                Self::NormalMessage { info, chain } => FFIForwardNode {
                    is_normal: true,
                    info: info.into_ffi(),
                    inner: ForwardNodeUnion {
                        normal: ManuallyDrop::new(chain.into_ffi()),
                    },
                },
                Self::ForwardMessage { info, forward: msg } => FFIForwardNode {
                    is_normal: false,
                    info: info.into_ffi(),
                    inner: ForwardNodeUnion {
                        forward: ManuallyDrop::new(msg.into_ffi()),
                    },
                },
            }
        }

        fn from_ffi(
            FFIForwardNode {
                is_normal,
                info,
                inner,
            }: Self::FFIValue,
        ) -> Self {
            unsafe {
                if is_normal {
                    Self::NormalMessage {
                        info: ForwardNodeInfo::from_ffi(info),
                        chain: MessageChain::from_ffi(ManuallyDrop::into_inner(inner.normal)),
                    }
                } else {
                    Self::ForwardMessage {
                        info: ForwardNodeInfo::from_ffi(info),
                        forward: ForwardMessage::from_ffi(ManuallyDrop::into_inner(inner.forward)),
                    }
                }
            }
        }
    }

    impl ForFFI for ForwardNodeInfo {
        type FFIValue = FFIForwardNodeInfo;

        fn into_ffi(self) -> Self::FFIValue {
            let ForwardNodeInfo {
                sender_id,
                sender_name,
                time,
            } = self;

            FFIForwardNodeInfo {
                sender_id,
                sender_name: sender_name.into(),
                time,
            }
        }

        fn from_ffi(
            FFIForwardNodeInfo {
                sender_id,
                sender_name,
                time,
            }: Self::FFIValue,
        ) -> Self {
            Self {
                sender_id,
                sender_name: sender_name.into(),
                time,
            }
        }
    }

    impl ForFFI for ForwardMessage {
        type FFIValue = RustVec<FFIForwardNode>;

        fn into_ffi(self) -> Self::FFIValue {
            self.0
                .into_iter()
                .map(ForwardNode::into_ffi)
                .collect::<Vec<FFIForwardNode>>()
                .into()
        }

        fn from_ffi(rs: Self::FFIValue) -> Self {
            Self(
                rs.into_vec()
                    .into_iter()
                    .map(ForwardNode::from_ffi)
                    .collect(),
            )
        }
    }
}