tmc_langs_util/
notification_reporter.rs

1//! Contains an utility for reporting warnings.
2
3use once_cell::sync::OnceCell;
4use serde::{Deserialize, Serialize};
5
6type NotificationClosure = Box<dyn 'static + Sync + Send + Fn(Notification)>;
7
8static NOTIFICATION_REPORTER: OnceCell<NotificationClosure> = OnceCell::new();
9
10/// Initializes the warning reporter with the given closure to be called with any warnings.
11/// Can only be initialized once, repeated calls do nothing.
12pub fn init(reporter: NotificationClosure) {
13    NOTIFICATION_REPORTER.get_or_init(|| reporter);
14}
15
16/// Calls the warning closure with the given warning.
17pub fn notify(notification: Notification) {
18    if let Some(reporter) = NOTIFICATION_REPORTER.get() {
19        reporter(notification);
20    }
21}
22
23#[derive(Debug, Serialize, Deserialize)]
24#[serde(rename_all = "kebab-case")]
25#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
26pub struct Notification {
27    notification_kind: NotificationKind,
28    message: String,
29}
30
31#[derive(Debug, Serialize, Deserialize)]
32#[serde(rename_all = "lowercase")]
33#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
34pub enum NotificationKind {
35    Warning,
36    Info,
37}
38
39impl Notification {
40    pub fn warning(message: impl ToString) -> Self {
41        Self {
42            notification_kind: NotificationKind::Warning,
43            message: message.to_string(),
44        }
45    }
46
47    pub fn info(message: impl ToString) -> Self {
48        Self {
49            notification_kind: NotificationKind::Info,
50            message: message.to_string(),
51        }
52    }
53}