-
-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathoutput.rs
More file actions
89 lines (72 loc) · 2.07 KB
/
output.rs
File metadata and controls
89 lines (72 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// SPDX-FileCopyrightText: Copyright © 2020-2026 Serpent OS Developers
//
// SPDX-License-Identifier: MPL-2.0
use std::sync::{Arc, OnceLock};
use crate::repository;
pub use self::tracing::TracingOutput;
pub use self::tui::TuiOutput;
mod tracing;
mod tui;
/// Default emitter used if [`install_emitter`] isn't called with a
/// custom [`Emit`] implementation.
pub type DefaultOutput = Chain<TracingOutput, TuiOutput>;
/// Global emitter either defaulted or installed via [`install_emitter`]
static EMITTER: OnceLock<Arc<dyn Emitter>> = OnceLock::new();
/// Install a global emitter that can be used with [`emit`]. If not called,
/// [`DefaultOutput`] is used.
///
/// This can only be called once. Future calls have no effect.
pub fn install_emitter(emitter: impl Emitter + 'static) {
let _ = EMITTER.set(Arc::new(emitter));
}
/// Get access to the global emitter
pub fn emitter() -> &'static dyn Emitter {
EMITTER.get_or_init(|| Arc::new(DefaultOutput::default())).as_ref()
}
/// Emit an event for output
#[macro_export]
macro_rules! emit {
($($tt:tt)*) => {
$crate::output::Event::emit(($($tt)*), $crate::output::emitter());
};
}
/// Defines how events are emitted to some output
pub trait Emitter: Send + Sync {
fn emit(&self, _event: &InternalEvent) {}
}
/// An emittable event
pub trait Event: Sized {
fn emit(self, _emitter: &dyn Emitter) {}
}
/// An internal `moss` library event
pub enum InternalEvent {
RepositoryManager(repository::manager::OutputEvent),
}
pub trait EmitExt: Emitter + Sized {
fn chain<U>(self, other: U) -> Chain<Self, U>
where
U: Emitter + Sized,
{
Chain { a: self, b: other }
}
}
/// Do nothing with / suppress all output
#[derive(Debug, Clone, Copy)]
pub struct NoopOutput;
impl Emitter for NoopOutput {}
/// Chains multiple emitters together
#[derive(Clone, Default)]
pub struct Chain<A, B> {
a: A,
b: B,
}
impl<A, B> Emitter for Chain<A, B>
where
A: Emitter,
B: Emitter,
{
fn emit(&self, event: &InternalEvent) {
self.a.emit(event);
self.b.emit(event);
}
}