aether/
endpoint.rs

1use std::{fs::File, io::BufWriter};
2
3use crate::{LogEntry, ENDPOINT_TYPE, LOGGER};
4
5/// Shorthand for the individual trait requirements for endpoints.
6///
7/// Automatically implemented for any type implementing the individual traits.
8pub trait EndpointSuper: std::any::Any + std::fmt::Debug + std::marker::Send {}
9impl<T: std::any::Any + std::fmt::Debug + std::marker::Send> EndpointSuper for T {}
10
11pub(crate) trait EndpointExt: EndpointSuper {
12    fn endpoint_hash(&self) -> EndpointHash;
13    fn fmt_message(&self, message: String) -> String;
14}
15
16impl<T: EndpointSuper + std::hash::Hash> EndpointExt for T {
17    fn endpoint_hash(&self) -> EndpointHash {
18        use std::hash::Hasher;
19
20        assert_eq!(ENDPOINT_TYPE.lock().unwrap().unwrap(), self.type_id());
21
22        let mut hasher = std::collections::hash_map::DefaultHasher::new();
23        self.hash(&mut hasher);
24        EndpointHash(hasher.finish())
25    }
26
27    fn fmt_message(&self, message: String) -> String {
28        let mut guard = LOGGER.lock().unwrap();
29        let logger = guard.as_mut().expect("Uninitialized logger. Did you forget to call `aether::init` or did you drop the `KeepAlive` object early?");
30        let fmt = logger
31            .fmt
32            .downcast_ref::<fn(LogEntry<T>) -> String>()
33            .unwrap();
34        fmt(LogEntry {
35            time: chrono::Utc::now(),
36            endpoint: self,
37            text: &message,
38        })
39    }
40}
41
42#[derive(Clone, Copy, Hash, PartialEq, Eq)]
43#[doc(hidden)]
44pub struct EndpointHash(u64);
45
46#[derive(Default)]
47pub(crate) struct Endpoint {
48    pub(crate) file: Option<BufWriter<File>>,
49    pub(crate) silent: bool,
50    pub(crate) disabled: bool,
51}