1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! # string_parser
//! 
//! string_parser is a crate that find tokens in source files and parse the inside<br/> 

use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn doc_test() {
        assert_eq!(string_parser("./text", "'", end_filter, callback).unwrap(), ());

        fn callback(s : String){
            println!("{}", s);
            if s != String::from("foo"){
                panic!();
            }
        }

        fn end_filter(c : Vec<char>) -> bool{
            for char in &c {
                print!("{}", char);
            }
            print!("\n");
            if c.last().unwrap() == &'\'' {
                println!("end filter");
                return true;
            }
            else {
                return false;
            }
        }
    }

    

    
}

//path : chemin d'acces du fichier
//txt : text to find
//filter function pointer pour la fin du string
//callback methode appelé a la fin
/// # Arguments
/// * `path` - the path to the file to search from
/// * `text` - the text to search
/// * `end_filter` - the function called at each character to check if we're still within the token. Sould return true when out of the token.
/// * `callback` - the function called when the text is exited. take the inside of the token as argument
/// # Examples
/// ./text being "...'foo'..."
/// ```no_run
/// extern crate string_parser;
/// use string_parser::string_parser; 
/// 
/// fn end_filter(c : Vec<char>) -> bool{            
///     if c.last().unwrap()== &'\'' {
///         return true;
///         }
///     else {
///         return false;
///         }   
/// }
/// 
/// fn callback(s : String){
///     assert_eq!(String::from("foo"), s);
/// }
/// string_parser("./text", "'", end_filter, callback).unwrap();
pub fn string_parser(path : &str,text : &str, end_filter : fn(Vec<char>) -> bool ,callback : fn(String)) -> Result<(), io::Error> {
    //open the file and put it as a string into file_buf
    let mut inside : bool = false; // true if the cursor is inside the statement
    let mut first : bool = true; // true is it's the first iteration
    let mut string_buffer = String::new();

    let mut file_buf = String::new(); //the whole file as a String
    let f = File::open(path)?;
    let mut f = BufReader::new(f);
    f.read_to_string(&mut file_buf)?;

    let mut buff : Vec<char> = vec![' '; text.len()];
    //loop through every character of the file
    for c in file_buf.chars() {
        let mut i : usize = 0;
        while i < buff.len() -1 {
            buff[i] = buff[i+1];
            i += 1;
        }
        buff[i] = c;
        i = 0;

        if inside && !end_filter(buff.clone()){
            string_buffer.push(c);
        }
        else if inside && !first {
            inside = false;
            // let s = string_buffer.pop();
            callback(string_buffer.clone());
        }
        else {
            while i < buff.len(){
                // println!("buff[{}] : {}, text[{}] : {}", i, buff[i], i, text.chars().nth(i).unwrap());
                if buff[i] != text.chars().nth(i).unwrap() {
                    break;
                }
                i += 1;
            }
            if i == text.len() {
                inside = true;
                first = false;
            }
        }
        

        

        

        


    }
    Ok(())
}