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 } } ;
22use directories:: UserDirs ;
33
44use crate :: constants;
@@ -10,18 +10,25 @@ use crate::constants;
1010/// the string passed to said printer will consist of one or more lines of text.
1111pub fn tail_scriptslog < P > ( printer : P , refresh_time_millis : u64 , cancel_token : Receiver < ( ) > , custom_path : Option < String > ) -> Option < String >
1212where P : Fn ( & String ) -> ( ) {
13+ let file_path: PathBuf ;
1314 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 ( ) ;
1516 } else {
1617 match scriptslog_file_path ( ) {
1718 Ok ( p) => {
18- tail_scriptslog_loop ( p , printer , refresh_time_millis , cancel_token )
19+ file_path = p ;
1920 }
2021 Err ( e) => {
21- Some ( e)
22+ return Some ( e) ;
2223 }
2324 }
2425 }
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)
2532}
2633
2734fn scriptslog_file_path ( ) -> Result < PathBuf , String > {
@@ -57,10 +64,13 @@ fn open_scriptslog(path: &PathBuf) -> Result<File, String> {
5764 . open ( path) ;
5865
5966 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+ }
6272 } else {
63- return Ok ( file. unwrap ( ) ) ;
73+ Ok ( file. unwrap ( ) )
6474 }
6575}
6676
@@ -72,6 +82,7 @@ where P: Fn(&String) -> () {
7282 let mut reader = BufReader :: new ( & file) ;
7383 // start from the end of the file
7484 let mut last_pos = reader. seek ( SeekFrom :: End ( 0 ) ) . unwrap ( ) ;
85+ let mut buffer = Vec :: new ( ) ;
7586 let mut text = String :: new ( ) ;
7687
7788 loop {
@@ -89,13 +100,14 @@ where P: Fn(&String) -> () {
89100 last_pos = reader. seek ( SeekFrom :: Start ( 0 ) ) . unwrap ( ) ;
90101 }
91102
103+ buffer. clear ( ) ;
92104 text. clear ( ) ;
93- match reader. read_to_string ( & mut text ) {
105+ match reader. read_to_end ( & mut buffer ) {
94106 Ok ( size) => {
95107 if size > 0 {
108+ text = String :: from_utf8_lossy ( & buffer) . trim ( ) . to_string ( ) ;
109+
96110 last_pos += size as u64 ;
97-
98- let text = text. trim ( ) . to_string ( ) ;
99111 printer ( & text) ;
100112 }
101113 }
@@ -126,6 +138,7 @@ where P: Fn(&String) -> () {
126138 }
127139 }
128140
141+ let mut buffer = Vec :: < u8 > :: new ( ) ;
129142 let mut text = String :: new ( ) ;
130143 loop {
131144 match cancel_token. try_recv ( ) {
@@ -147,13 +160,14 @@ where P: Fn(&String) -> () {
147160 reader. seek ( SeekFrom :: Start ( last_pos) ) . unwrap ( ) ;
148161 }
149162
163+ buffer. clear ( ) ;
150164 text. clear ( ) ;
151- match reader. read_to_string ( & mut text ) {
165+ match reader. read_to_end ( & mut buffer ) {
152166 Ok ( size) => {
153167 if size > 0 {
168+ text = String :: from_utf8_lossy ( & buffer) . trim ( ) . to_string ( ) ;
169+
154170 last_pos += size as u64 ;
155-
156- let text = text. trim ( ) . to_string ( ) ;
157171 printer ( & text) ;
158172 }
159173 }
0 commit comments