1use chrono::prelude::*;
2use fs2::FileExt;
3
4use std::fs::{OpenOptions};
5use std::io::{BufReader, BufRead, Write, Seek, SeekFrom};
6use std::env;
7pub fn log(s: &str) {
8 let path = std::env::current_exe().unwrap();
9 let filename = std::path::Path::new(&path).file_name().unwrap().to_str().unwrap();
10
11 let home_dir = get_home_dir().unwrap_or_else(|| String::from("."));
12 let path;
13 if cfg!(target_os = "windows") {
14 path = format!("{}/AppData/Local/Wei/{}.log.txt", home_dir, filename);
15 } else {
16 path = format!("{}/.wei/{}.log.txt", home_dir, filename);
17 }
18
19 if !std::path::Path::new(&path).exists() {
20 match std::fs::create_dir_all(std::path::Path::new(&path).parent().unwrap()) {
21 Ok(_) => (),
22 Err(_) => return,
23 };
24 }
25
26 let local: DateTime<Local> = Local::now();
27 let data = format!("{} {}",local.format("%Y-%m-%d %H:%M"), s);
28
29 #[cfg(target_os = "windows")]
30 match write_and_prune_file(&path, &data, 10000) {
31 Ok(_) => (),
32 Err(_) => return,
33 };
34
35 #[cfg(not(target_os = "windows"))] {
36 let mut file = match OpenOptions::new().read(true).write(true).create(true).open(&path) {
37 Ok(file) => file,
38 Err(_) => return,
39 };
40 let reader = BufReader::new(&file);
41 let mut lines: Vec<String> = match reader.lines().collect::<Result<_, _>>() {
42 Ok(lines) => lines,
43 Err(_) => return,
44 };
45 lines.push(data);
46 if lines.len() > 10000 {
47 lines.remove(0);
48 }
49 match file.seek(SeekFrom::Start(0)) {
50 Ok(_) => (),
51 Err(_) => return,
52 };
53 match file.set_len(0) {
54 Ok(_) => (),
55 Err(_) => return,
56 }; let mut writer = std::io::BufWriter::new(&file);
58 for line in &lines {
59 match writeln!(writer, "{}", line) {
60 Ok(_) => (),
61 Err(_) => return,
62 };
63 }
64 }
65}
66
67#[macro_export]
68macro_rules! info {
69 ($($arg:tt)*) => {{
70 let message = format!($($arg)*);
71 crate::wei_log::log(&message); }}
74}
75
76#[macro_export]
77macro_rules! error {
78 ($($arg:tt)*) => {{
79 let message = format!($($arg)*);
80 let message = format!("错误: {}", message);
81 crate::wei_log::log(&message); }}
84}
85
86#[macro_export]
87macro_rules! info_println {
88 ($($arg:tt)*) => {{
89 let message = format!($($arg)*);
90 crate::wei_log::log(&message); }}
93}
94
95#[macro_export]
96macro_rules! info_print {
97 ($($arg:tt)*) => {{
98 let message = format!($($arg)*);
99 crate::wei_log::log(&message); }}
102}
103
104
105fn get_home_dir() -> Option<String> {
106 if cfg!(target_os = "windows") {
107 env::var("USERPROFILE").ok()
108 } else {
109 env::var("HOME").ok()
110 }
111}
112
113fn write_and_prune_file(path: &str, content: &str, max_lines: usize) -> std::io::Result<()> {
114 let mut file = OpenOptions::new().read(true).write(true).create(true).open(path)?;
115
116 file.lock_exclusive()?;
117
118 let reader = BufReader::new(&file);
120 let mut lines: Vec<String> = reader.lines().collect::<Result<_, _>>()?;
121
122 if lines.len() >= max_lines {
124 lines.remove(lines.len() - 1);
125 }
126
127 lines.insert(0, content.to_string());
129
130 file.seek(SeekFrom::Start(0))?;
132 file.set_len(0)?; for line in &lines {
134 writeln!(file, "{}", line)?;
135 }
136
137 file.unlock()?;
138
139 Ok(())
140}
141
142
143
144