@@ -21,9 +21,11 @@ pub use self::MacroFormat::*;
2121
2222use std:: cell:: RefCell ;
2323use std:: ops:: { Add , Sub } ;
24+ use std:: path:: Path ;
2425use std:: rc:: Rc ;
2526
26- use std:: fmt;
27+ use std:: { fmt, fs} ;
28+ use std:: io:: { self , Read } ;
2729
2830use serialize:: { Encodable , Decodable , Encoder , Decoder } ;
2931
@@ -527,24 +529,66 @@ impl FileMap {
527529 }
528530}
529531
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+ }
530555
531556// _____________________________________________________________________________
532557// CodeMap
533558//
534559
535560pub struct CodeMap {
536561 pub files : RefCell < Vec < Rc < FileMap > > > ,
537- expansions : RefCell < Vec < ExpnInfo > >
562+ expansions : RefCell < Vec < ExpnInfo > > ,
563+ file_loader : Box < FileLoader >
538564}
539565
540566impl CodeMap {
541567 pub fn new ( ) -> CodeMap {
542568 CodeMap {
543569 files : RefCell :: new ( Vec :: new ( ) ) ,
544570 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
545580 }
546581 }
547582
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+
548592 pub fn new_filemap ( & self , filename : FileName , mut src : String ) -> Rc < FileMap > {
549593 let mut files = self . files . borrow_mut ( ) ;
550594 let start_pos = match files. last ( ) {
0 commit comments