@@ -21,9 +21,11 @@ pub use self::MacroFormat::*;
21
21
22
22
use std:: cell:: RefCell ;
23
23
use std:: ops:: { Add , Sub } ;
24
+ use std:: path:: Path ;
24
25
use std:: rc:: Rc ;
25
26
26
- use std:: fmt;
27
+ use std:: { fmt, fs} ;
28
+ use std:: io:: { self , Read } ;
27
29
28
30
use serialize:: { Encodable , Decodable , Encoder , Decoder } ;
29
31
@@ -527,24 +529,66 @@ impl FileMap {
527
529
}
528
530
}
529
531
532
+ /// An abstraction over the fs operations used by the Parser.
533
+ pub trait FileLoader {
534
+ /// Query the existence of a file.
535
+ fn file_exists ( & self , path : & Path ) -> bool ;
536
+
537
+ /// Read the contents of an UTF-8 file into memory.
538
+ fn read_file ( & self , path : & Path ) -> io:: Result < String > ;
539
+ }
540
+
541
+ /// A FileLoader that uses std::fs to load real files.
542
+ pub struct RealFileLoader ;
543
+
544
+ impl FileLoader for RealFileLoader {
545
+ fn file_exists ( & self , path : & Path ) -> bool {
546
+ fs:: metadata ( path) . is_ok ( )
547
+ }
548
+
549
+ fn read_file ( & self , path : & Path ) -> io:: Result < String > {
550
+ let mut src = String :: new ( ) ;
551
+ try!( try!( fs:: File :: open ( path) ) . read_to_string ( & mut src) ) ;
552
+ Ok ( src)
553
+ }
554
+ }
530
555
531
556
// _____________________________________________________________________________
532
557
// CodeMap
533
558
//
534
559
535
560
pub struct CodeMap {
536
561
pub files : RefCell < Vec < Rc < FileMap > > > ,
537
- expansions : RefCell < Vec < ExpnInfo > >
562
+ expansions : RefCell < Vec < ExpnInfo > > ,
563
+ file_loader : Box < FileLoader >
538
564
}
539
565
540
566
impl CodeMap {
541
567
pub fn new ( ) -> CodeMap {
542
568
CodeMap {
543
569
files : RefCell :: new ( Vec :: new ( ) ) ,
544
570
expansions : RefCell :: new ( Vec :: new ( ) ) ,
571
+ file_loader : Box :: new ( RealFileLoader )
572
+ }
573
+ }
574
+
575
+ pub fn with_file_loader ( file_loader : Box < FileLoader > ) -> CodeMap {
576
+ CodeMap {
577
+ files : RefCell :: new ( Vec :: new ( ) ) ,
578
+ expansions : RefCell :: new ( Vec :: new ( ) ) ,
579
+ file_loader : file_loader
545
580
}
546
581
}
547
582
583
+ pub fn file_exists ( & self , path : & Path ) -> bool {
584
+ self . file_loader . file_exists ( path)
585
+ }
586
+
587
+ pub fn load_file ( & self , path : & Path ) -> io:: Result < Rc < FileMap > > {
588
+ let src = try!( self . file_loader . read_file ( path) ) ;
589
+ Ok ( self . new_filemap ( path. to_str ( ) . unwrap ( ) . to_string ( ) , src) )
590
+ }
591
+
548
592
pub fn new_filemap ( & self , filename : FileName , mut src : String ) -> Rc < FileMap > {
549
593
let mut files = self . files . borrow_mut ( ) ;
550
594
let start_pos = match files. last ( ) {
0 commit comments