1use super::listener_logger::ListenerInspectLogger;
6use crate::service_context::ExternalServiceEvent;
7use anyhow::{anyhow, Error};
8use futures::channel::mpsc::UnboundedSender;
9use std::cell::Cell;
10use std::marker::PhantomData;
11use std::rc::Rc;
12
13#[derive(Clone)]
14pub enum Direction {
15 Request(String),
16 Response(String, ResponseType),
17}
18
19#[derive(Clone)]
20pub struct UsageEvent {
21 pub setting: &'static str,
22 pub request_type: RequestType,
23 pub direction: Direction,
24 pub id: u64,
25}
26
27pub trait Nameable {
28 const NAME: &str;
29}
30
31#[derive(Clone)]
32pub struct UsagePublisher<T> {
33 id_gen: Rc<Cell<u64>>,
34 inspect_tx: UnboundedSender<UsageEvent>,
35 listener_logger: Rc<ListenerInspectLogger>,
36 _phantom: PhantomData<T>,
37}
38
39impl<T> UsagePublisher<T> {
40 pub fn new(
41 inspect_tx: UnboundedSender<UsageEvent>,
42 listener_logger: Rc<ListenerInspectLogger>,
43 ) -> Self {
44 Self { id_gen: Rc::new(Cell::new(0)), inspect_tx, listener_logger, _phantom: PhantomData }
45 }
46}
47
48impl<T> UsagePublisher<T>
49where
50 T: Nameable,
51{
52 pub fn request(&self, request: String, request_type: RequestType) -> UsageResponsePublisher<T> {
53 let id = self.id_gen.get();
54 self.id_gen.set(id.wrapping_add(1));
55 let _ = self.inspect_tx.unbounded_send(UsageEvent {
56 setting: T::NAME,
57 request_type,
58 direction: Direction::Request(request),
59 id,
60 });
61 if let RequestType::Get = request_type {
62 self.listener_logger.add_listener(T::NAME.into());
63 }
64
65 UsageResponsePublisher {
66 id,
67 request_type,
68 inspect_tx: self.inspect_tx.clone(),
69 listener_logger: Rc::clone(&self.listener_logger),
70 sent: false,
71 _phantom: PhantomData,
72 }
73 }
74}
75
76#[derive(Clone)]
77pub struct UsageResponsePublisher<T> {
78 id: u64,
79 request_type: RequestType,
80 inspect_tx: UnboundedSender<UsageEvent>,
81 listener_logger: Rc<ListenerInspectLogger>,
82 sent: bool,
83 _phantom: PhantomData<T>,
84}
85
86impl<T> UsageResponsePublisher<T>
87where
88 T: Nameable,
89{
90 pub fn respond(mut self, response: String, response_type: ResponseType) {
91 let _ = self.inspect_tx.unbounded_send(UsageEvent {
92 setting: T::NAME,
93 request_type: self.request_type,
94 direction: Direction::Response(response, response_type),
95 id: self.id,
96 });
97 if let RequestType::Get = self.request_type {
98 self.listener_logger.remove_listener(T::NAME.into());
99 }
100 self.sent = true;
101 }
102}
103
104impl<T> Drop for UsageResponsePublisher<T> {
105 fn drop(&mut self) {
106 if !self.sent {
107 log::error!("UsageResponsePublisher dropped without sending response");
108 }
109 }
110}
111
112#[derive(Copy, Clone, Debug)]
113pub enum RequestType {
114 Get,
115 Set,
116 Camera,
117 MediaButtons,
118}
119
120#[derive(Debug, Copy, Clone)]
121pub enum ResponseType {
125 OkSome,
126 OkNone,
127 UnimplementedRequest,
128 StorageFailure,
129 InitFailure,
130 RestoreFailure,
131 InvalidArgument,
132 IncompatibleArguments,
133 ExternalFailure,
134 UnhandledType,
135 DeliveryError,
136 UnexpectedError,
137 UndeliverableError,
138 UnsupportedError,
139 CommunicationError,
140 IrrecoverableError,
141 TimeoutError,
142 AlreadySubscribed,
143}
144
145#[derive(Copy, Clone, Debug)]
146pub struct MediaButtons {
147 pub mic_mute: Option<bool>,
148 pub camera_disable: Option<bool>,
149}
150
151#[derive(Clone)]
152pub struct SettingValuePublisher<T> {
153 tx: UnboundedSender<(&'static str, String)>,
154 _phantom: PhantomData<T>,
155}
156
157impl<T> SettingValuePublisher<T> {
158 pub fn new(tx: UnboundedSender<(&'static str, String)>) -> Self {
159 Self { tx, _phantom: PhantomData }
160 }
161}
162
163impl<T> SettingValuePublisher<T>
164where
165 T: Nameable + std::fmt::Debug,
166{
167 pub fn publish(&self, value: &T) -> Result<(), Error> {
168 self.tx
169 .unbounded_send((T::NAME, format!("{value:?}")))
170 .map_err(|e| anyhow!("Unable to send setting_value update: {e:?}"))
171 }
172}
173
174#[derive(Clone)]
175pub struct ExternalEventPublisher {
176 tx: UnboundedSender<ExternalServiceEvent>,
177}
178
179impl ExternalEventPublisher {
180 pub fn new(tx: UnboundedSender<ExternalServiceEvent>) -> Self {
181 Self { tx }
182 }
183
184 pub fn publish(&self, event: ExternalServiceEvent) -> Result<(), Error> {
185 self.tx
186 .unbounded_send(event)
187 .map_err(|e| anyhow!("Unable to send external event update: {e:?}"))
188 }
189}