1use crate::logging::LogLocation;
2use chrono::prelude::*;
3use std::fmt::Debug;
4
5#[derive(Debug)]
8pub struct Formatter {}
9
10impl Formatter {
11 pub fn header(&self, now: &DateTime<Utc>, log_location: &LogLocation) -> String {
12 format!(
13 "[{} {:?} {} {}:{}]",
14 now.time().format("%H:%M:%S").to_string(),
15 log_location.thread_id,
16 log_location.file_path,
17 log_location.func_path,
18 log_location.lineno
19 )
20 }
21
22 pub fn q(&self) -> String {
23 format!(">")
24 }
25
26 pub fn q_literal<T: Debug>(&self, val: &T) -> String {
44 format!("> {:?}", val)
45 }
46
47 pub fn q_expr<T: Debug>(&self, val: &T, expr: &str) -> String {
66 format!("> {} = {:?}", expr, val)
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use std::thread;
74
75 macro_rules! ll {
76 ($filep: expr, $funcp:expr, $lineno: expr) => {
77 (
78 LogLocation {
79 file_path: String::from($filep),
80 func_path: String::from($funcp),
81 lineno: $lineno,
82 thread_id: thread::current().id(),
83 },
84 thread::current().id(),
85 )
86 };
87 }
88
89 #[test]
90 fn test_header() {
91 let formatter = Formatter {};
92 let (loc, tid) = ll!("src/lib.rs", "q_debug::tests::test_q", 42);
93
94 assert_eq!(
95 formatter.header(&Utc.ymd(2020, 6, 22).and_hms(20, 5, 32), &loc),
96 format!("[20:05:32 {:?} src/lib.rs q_debug::tests::test_q:42]", tid)
97 );
98 }
99
100 #[test]
101 fn test_q() {
102 let formatter = Formatter {};
103
104 assert_eq!(formatter.q(), ">");
105 }
106 #[test]
108 fn test_q_literal() {
109 let formatter = Formatter {};
110
111 assert_eq!(
112 formatter.q_literal(&String::from("Hello, world!")),
113 "> \"Hello, world!\""
114 );
115 assert_eq!(formatter.q_literal(&1), "> 1");
116 }
117
118 #[test]
119 fn test_q_expr() {
120 let formatter = Formatter {};
121
122 assert_eq!(
123 formatter.q_expr(&String::from("Hello, world!"), &String::from("my_var")),
124 "> my_var = \"Hello, world!\""
125 );
126 assert_eq!(
127 formatter.q_expr(&Some(42), &String::from("a_function(42)")),
128 "> a_function(42) = Some(42)"
129 );
130 }
131}