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
use crate::*;
use std::sync::Arc;


/// Source type is used to store the absolute path of the source logger. A source must be started with
/// logger, and can have any number layers of session. This type cannot be constructed outside of the
/// library.
#[derive(Debug, Clone)]
pub struct Source(Vec<Arc<str>>);


impl Source {
  pub(crate) fn new(logger: impl Into<String>) -> Self {
    Self(vec![logger.into().into()])
  }

  pub(crate) fn session(&self, session: impl Into<String>) -> Self {
    let mut src = self.0.iter().cloned().collect::<Vec<_>>();
    src.push(session.into().into());

    Self(src)
  }

  /// Returns the raw `Rc<str>` slice.
  pub fn raw(&self) -> &[Arc<str>] {
    &self.0
  }

  /// Returns the number of layers of the source.
  pub fn len(&self) -> usize {
    self.0.len()
  }

  /// Checks if the source is from the logger.
  pub fn is_from_logger(&self) -> bool {
    self.0.len() == 1
  }

  /// Checks if the source is from the session.
  pub fn is_from_session(&self) -> bool {
    self.0.len() > 1
  }

  /// Get the logger name.
  pub fn logger(&self) -> &Arc<str> {
    self.0.first().unwrap()
  }
}


impl Output for Source {
  fn for_write(&self, f: &mut impl std::fmt::Write) {
    write!(f, "{}", self.0.first().unwrap()).unwrap();

    if self.0.len() > 1 {
      write!(f, ":{}", self.0.last ().unwrap()).unwrap();
    }
  }

  fn for_print(&self, f: &mut impl std::fmt::Write) {
    write!(f, "{}", self.0.join(":")).unwrap();
  }
}