/* contents of info.txt
[Title]
Plane
[AKA]
The Plane
[Year]
2023
*/
use std::fs;
fn find6<'a>(input: &'a str, key: &str) -> Option<&'a str> {
let mut found = false;
for line in input.lines() {
// ... you know you return the line AFTER the line where you found key, right?
if !found {
return Some(line);
} else if line.contains(key) {
found = true;
}
}
None
}
fn main() {
// ? file
let filename = "info.txt";
// ? var
let mut title: &str = "";
let mut aka = String::new();
// ? open file
let contents = fs::read_to_string(filename)
.expect("Except: file not found ");
let info_txt=contents.split("\n");
for line in info_txt {
if line.contains("[Title]") {
title = find(&contents, &line);
}
} // end for line
println!("Original title -> {}", title);
I unmingled your example and made a version that compiles on the playground (panics, because the file we read from doesn't exist):
use std::fs;
fn find<'a>(input: &'a str, key: &str) -> Option<&'a str> {
let mut found = false;
for line in input.lines() {
// ... you know you return the line AFTER the line where you found `key`, right?
if !found {
return Some(line);
} else if line.contains(key) {
found = true;
}
}
None
}
fn main() {
// ? file
let filename = "info.txt";
// ? var
let mut title: &str = "";
let mut aka = String::new();
let mut year = String::new();
let reader = String::new();
// ? open file
let contents = fs::read_to_string(filename).expect("Except: file not found ");
for line in contents.lines() {
if line.contains("title") {
title = find(&reader, &line).unwrap_or("");
}
} // end for line
println!("Original title -> {}", title);
}
Your find function must return something. If you never found key in any line of input, what would your function return? You must make sure it returns an instance of the right type. I used the Option type as a return type instead of String for this. I think this'd be the appropriate type to return in such situations where you might return something, but if you don't find anything, you return nothing. Either you find the key, in which case you return Some(line), or you don't, so you return None.
This is more performant, as this does not involve copying. I've added this into the example above as well.
// var
let mut title = String::new();
let mut aka = String::new();
let mut year = String::new();
// open file
let contents = fs::read_to_string(filename)
.expect("Except: file not found ");
let info_txt=contents.split("\n");
for line in info_txt {
if line.contains("[Title]") {
title = find(&contents, &line);
}
} // end for line
println!("Original title -> {}", title);
}
OUTPUT ERROR:
fn find(input: &str, key: &str) -> String { // Test...
| ------ expected std::string::String because of return type
In your find() function, if the line [Title] or [AKA] or [Year] isn't found, the for loop will complete, and you pass out the end of the function without returning anything. That's what the compiler is complaining about here. You may know that the data file your are loading contains all these lines, but the compiler can't know that.
Some options have been provided in this thread; @jofas suggested an Option<> type, and returning None if the line isn't found. But you will have to resolve this problem (and maybe a few more that are uncovered once you solve this problem) before the code will compile.