clipboard_stream/
body.rs

1use std::sync::{Arc, Mutex};
2
3use futures::channel::mpsc::{Sender, TrySendError};
4
5use crate::{Error, Msg};
6
7/// Various kind of clipboard items.
8#[derive(Debug, Clone)]
9pub enum Body {
10    /// UTF-8 encoded String.
11    Utf8String(String),
12}
13
14/// Specifies the kind of [`ClipboardStream`].
15///
16/// [`ClipboardStream`]: crate::ClipboardStream
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum Kind {
19    /// UTF-8 encoded String.
20    Utf8String,
21}
22
23#[derive(Debug)]
24pub(crate) struct BodySenders {
25    utf8_string_tx: Option<Sender<Msg>>,
26}
27
28impl BodySenders {
29    pub(crate) fn new() -> Self {
30        BodySenders {
31            utf8_string_tx: None,
32        }
33    }
34
35    /// Register Sender that was specified kind. If, sender already exists, return Err(Error::StreamAlreadyExists).
36    pub(crate) fn register(&mut self, tx: Sender<Msg>, kind: &Kind) -> Result<(), Error> {
37        if self.is_some(kind) {
38            return Err(Error::StreamAlreadyExists);
39        }
40
41        match kind {
42            Kind::Utf8String => self.utf8_string_tx = Some(tx),
43        }
44
45        Ok(())
46    }
47
48    fn is_some(&self, kind: &Kind) -> bool {
49        match kind {
50            Kind::Utf8String => self.utf8_string_tx.is_some(),
51        }
52    }
53
54    /// Close channel and unregister sender that was specified kind
55    fn unregister(&mut self, kind: &Kind) {
56        match kind {
57            Kind::Utf8String => {
58                if let Some(ref mut v) = self.utf8_string_tx {
59                    if !v.is_closed() {
60                        v.close_channel();
61                    }
62                    self.utf8_string_tx = None;
63                }
64            }
65        }
66    }
67
68    /// When specified kind's Sender is Some, send message.
69    pub(crate) fn try_send_if_some(
70        &mut self,
71        msg: Msg,
72        kind: &Kind,
73    ) -> Result<(), TrySendError<Msg>> {
74        match kind {
75            Kind::Utf8String => try_send(&mut self.utf8_string_tx, msg)?,
76        }
77        Ok(())
78    }
79
80    #[allow(dead_code)]
81    /// Send a message to the sender if available.
82    /// Errors are logged but do not stop other sends.
83    pub(crate) fn send_all_if_some(&mut self, msg: Msg) {
84        send_ignore_err(&mut self.utf8_string_tx, msg);
85    }
86}
87
88#[inline]
89fn try_send(tx: &mut Option<Sender<Msg>>, msg: Msg) -> Result<(), TrySendError<Msg>> {
90    if let Some(v) = tx {
91        v.try_send(msg)?
92    }
93    Ok(())
94}
95
96#[allow(dead_code)]
97#[inline]
98fn send_ignore_err(tx: &mut Option<Sender<Msg>>, msg: Msg) {
99    if let Some(v) = tx
100        && let Err(e) = v.try_send(msg)
101    {
102        eprintln!("{}", e);
103    }
104}
105
106/// Handler for Cleaning up buffer(channel).
107///
108/// Close channel and unregister a specified kined of sender.
109#[derive(Debug)]
110pub(crate) struct BodySendersDropHandle(Arc<Mutex<BodySenders>>);
111
112impl BodySendersDropHandle {
113    pub(crate) fn new(senders: Arc<Mutex<BodySenders>>) -> Self {
114        BodySendersDropHandle(senders)
115    }
116
117    pub(crate) fn drop(&mut self, kind: &Kind) {
118        let mut gurad = self.0.lock().unwrap();
119        gurad.unregister(kind);
120    }
121}