1
- use std:: { fs:: { File , OpenOptions } , sync:: mpsc:: { Receiver , TryRecvError } , io:: { BufReader , Seek , SeekFrom , Read } , time:: Duration , path:: { Path , PathBuf } } ;
1
+ use std:: { fs:: { File , OpenOptions } , sync:: mpsc:: { Receiver , TryRecvError } , io:: { BufReader , Seek , SeekFrom , Read , self } , time:: Duration , path:: { Path , PathBuf } } ;
2
2
use directories:: UserDirs ;
3
3
4
4
use crate :: constants;
@@ -10,18 +10,25 @@ use crate::constants;
10
10
/// the string passed to said printer will consist of one or more lines of text.
11
11
pub fn tail_scriptslog < P > ( printer : P , refresh_time_millis : u64 , cancel_token : Receiver < ( ) > , custom_path : Option < String > ) -> Option < String >
12
12
where P : Fn ( & String ) -> ( ) {
13
+ let file_path: PathBuf ;
13
14
if let Some ( p) = custom_path {
14
- tail_scriptslog_loop ( Path :: new ( & p) . to_path_buf ( ) , printer , refresh_time_millis , cancel_token )
15
+ file_path = Path :: new ( & p) . to_path_buf ( ) ;
15
16
} else {
16
17
match scriptslog_file_path ( ) {
17
18
Ok ( p) => {
18
- tail_scriptslog_loop ( p , printer , refresh_time_millis , cancel_token )
19
+ file_path = p ;
19
20
}
20
21
Err ( e) => {
21
- Some ( e)
22
+ return Some ( e) ;
22
23
}
23
24
}
24
25
}
26
+
27
+ if !file_path. exists ( ) {
28
+ println ! ( "Log file at location {} does not yet exist. Trying to create a new one..." , file_path. to_string_lossy( ) ) ;
29
+ }
30
+
31
+ tail_scriptslog_loop ( file_path, printer, refresh_time_millis, cancel_token)
25
32
}
26
33
27
34
fn scriptslog_file_path ( ) -> Result < PathBuf , String > {
@@ -57,10 +64,13 @@ fn open_scriptslog(path: &PathBuf) -> Result<File, String> {
57
64
. open ( path) ;
58
65
59
66
if let Err ( e) = file {
60
- println ! ( "{:?}" , e. kind( ) ) ;
61
- return Err ( "File open error: " . to_owned ( ) + & e. to_string ( ) ) ;
67
+ if e. kind ( ) == io:: ErrorKind :: NotFound {
68
+ Err ( "File open error: At least one of the directory components of the file path does not exist." . to_owned ( ) )
69
+ } else {
70
+ Err ( "File open error: " . to_owned ( ) + & e. to_string ( ) )
71
+ }
62
72
} else {
63
- return Ok ( file. unwrap ( ) ) ;
73
+ Ok ( file. unwrap ( ) )
64
74
}
65
75
}
66
76
@@ -72,6 +82,7 @@ where P: Fn(&String) -> () {
72
82
let mut reader = BufReader :: new ( & file) ;
73
83
// start from the end of the file
74
84
let mut last_pos = reader. seek ( SeekFrom :: End ( 0 ) ) . unwrap ( ) ;
85
+ let mut buffer = Vec :: new ( ) ;
75
86
let mut text = String :: new ( ) ;
76
87
77
88
loop {
@@ -89,13 +100,14 @@ where P: Fn(&String) -> () {
89
100
last_pos = reader. seek ( SeekFrom :: Start ( 0 ) ) . unwrap ( ) ;
90
101
}
91
102
103
+ buffer. clear ( ) ;
92
104
text. clear ( ) ;
93
- match reader. read_to_string ( & mut text ) {
105
+ match reader. read_to_end ( & mut buffer ) {
94
106
Ok ( size) => {
95
107
if size > 0 {
108
+ text = String :: from_utf8_lossy ( & buffer) . trim ( ) . to_string ( ) ;
109
+
96
110
last_pos += size as u64 ;
97
-
98
- let text = text. trim ( ) . to_string ( ) ;
99
111
printer ( & text) ;
100
112
}
101
113
}
@@ -126,6 +138,7 @@ where P: Fn(&String) -> () {
126
138
}
127
139
}
128
140
141
+ let mut buffer = Vec :: < u8 > :: new ( ) ;
129
142
let mut text = String :: new ( ) ;
130
143
loop {
131
144
match cancel_token. try_recv ( ) {
@@ -147,13 +160,14 @@ where P: Fn(&String) -> () {
147
160
reader. seek ( SeekFrom :: Start ( last_pos) ) . unwrap ( ) ;
148
161
}
149
162
163
+ buffer. clear ( ) ;
150
164
text. clear ( ) ;
151
- match reader. read_to_string ( & mut text ) {
165
+ match reader. read_to_end ( & mut buffer ) {
152
166
Ok ( size) => {
153
167
if size > 0 {
168
+ text = String :: from_utf8_lossy ( & buffer) . trim ( ) . to_string ( ) ;
169
+
154
170
last_pos += size as u64 ;
155
-
156
- let text = text. trim ( ) . to_string ( ) ;
157
171
printer ( & text) ;
158
172
}
159
173
}
0 commit comments