Skip to main content

egui_charts/services/
sharing.rs

1//! Sharing of layouts and watchlists through the host's own accounts and storage.
2
3use crate::data::{MaybeSend, Reply};
4
5/// What a [`Sharing`] service shares.
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7#[non_exhaustive]
8pub enum ShareKind {
9    /// A named chart layout, as kept in [`StoreKind::Layouts`](super::StoreKind::Layouts).
10    Layout,
11    /// A watchlist, by its name.
12    Watchlist,
13}
14
15/// A view-only link to a shared document and what its recipient may do with it.
16#[derive(Clone, Debug, PartialEq, Eq)]
17#[non_exhaustive]
18pub struct ShareLink {
19    /// The link, which opens the document for viewing only.
20    pub url: String,
21    /// Whether a recipient may save a copy of the document.
22    pub copy_allowed: bool,
23}
24
25impl ShareLink {
26    /// A view-only link to `url`, whose recipient may save a copy when `copy_allowed`.
27    pub fn new(url: impl Into<String>, copy_allowed: bool) -> Self {
28        Self {
29            url: url.into(),
30            copy_allowed,
31        }
32    }
33}
34
35/// The sharing operations a [`Sharing`] service offers for one [`ShareKind`].
36#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
37#[non_exhaustive]
38pub struct ShareOffer {
39    /// Whether [`Sharing::link`] is available.
40    pub link: bool,
41    /// Whether [`Sharing::copy`] is available.
42    pub copy: bool,
43}
44
45impl ShareOffer {
46    /// An offer of the operations the flags name.
47    pub fn new(link: bool, copy: bool) -> Self {
48        Self { link, copy }
49    }
50}
51
52/// Sharing a layout or watchlist, supplied by a host that has accounts and somewhere to keep
53/// shared documents. The library owns neither: it shows the controls the host offers and reports
54/// the host's answers. Without a service the layout menu and the watchlist panel offer no sharing.
55///
56/// Methods are called on the UI thread and return at once; answer through the [`Reply`] you were
57/// given, from any thread, runtime or browser task. Answer an error, such as
58/// [`FeedError::Other`](crate::data::FeedError::Other) with the reason, to reject an operation:
59/// the menu shows it. The documents are the ones the host already holds under `name`.
60pub trait Sharing: MaybeSend + 'static {
61    /// Which operations to offer for `kind`. The default offers none.
62    fn offers(&self, kind: ShareKind) -> ShareOffer {
63        let _ = kind;
64        ShareOffer::default()
65    }
66
67    /// A view-only link to the document `name` of `kind`. The library copies the link to the
68    /// clipboard and tells the user whether a recipient may save a copy.
69    fn link(&self, kind: ShareKind, name: &str, reply: Reply<ShareLink>) {
70        let _ = (kind, name);
71        reply.send(Err(crate::data::FeedError::NotSupported));
72    }
73
74    /// Saves a copy of the document `name` of `kind` for the user and answers the copy's name.
75    /// A layout copy is read back from [`Storage`](super::Storage), so the host writes it
76    /// there; a watchlist copy is added to the panel's lists under the answered name.
77    fn copy(&self, kind: ShareKind, name: &str, reply: Reply<String>) {
78        let _ = (kind, name);
79        reply.send(Err(crate::data::FeedError::NotSupported));
80    }
81}