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}