[SOLVED] 's' does not live long enough

Hello, i need some help.
I want to look for lines that match a certain regex-pattern in a file and then count those that are the same and save the result in a HashMap<String,u32>.

use regex::Regex;
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::{self, prelude::*};
use std::path::Path;

const MAXCOUNT: u8 = 3;

fn get_file_as_byte_vec(filename: &Path) -> Vec<u8> {
    let mut f = File::open(filename).expect("no file found");
    let metadata = fs::metadata(filename).expect("unable to read metadata");
    let mut buffer = vec![0; metadata.len() as usize];
    f.read_exact(&mut buffer).expect("buffer overflow");
    buffer
}

fn main() -> io::Result<()> {
    let filename = "file.txt";
    let path = Path::new(filename);

    // file sometimes has non UTF-8 conform bytes , so I check before and skip incalid lines
    let buf: Vec<String> = get_file_as_byte_vec(path)
        .split(|i| *i == 10)
        .map(|b| match String::from_utf8(b.to_vec()) {
            Ok(v) => v,
            Err(_e) => String::from(""),
        })
        .collect();
    let mut result: HashMap<&str, u32> = HashMap::new();
    let re = Regex::new(r"read (.+\.hl7)\. .+read").unwrap();
    for s in buf {
        if let Some(v) = re.captures(&s) {
            println!("{}", v.get(1).unwrap().as_str());
            // let x = v.get(1).unwrap().as_str();
            //let count = result.entry(x).or_insert(0);
            //*count += 1;
        } else {
            continue;
        };
    }

    //TODO
    //check result if some key has count >MAXCOUNT

    Ok(())
}

til here it works fine and prints the lines that match.
when I uncomment the three lines in the last for-loop

let x = v.get(1).unwrap().as_str();
let count = result.entry(x).or_insert(0);
*count += 1;

I get an error in the "if let Some(v).... " line.

can anybody help?
Thanks

This fixes the issue, by making sure buf is not consumed (and its elements dropped) by the loop:

-   for s in buf {
+   for s in &buf {
1 Like

This line borrows the substring of the match for the lifetime of the capture, which is the lifetime of the iterator item s:

Therefore you can't hace references to it in your HashMap since s will only live for the lifetime of its loop iteration.

You should instead construct a HashMap of owned values (HashMap<String, u32>).

thanks moy2010
This was the solution.