Rust allows structs to hold mutable references to owned data, enabling them to modify the data in-place. This requires a deep understanding of lifetimes and Rust's borrowing rules to ensure memory safety.
In this challenge, you will implement a struct named MutableTextFinder
that holds a mutable reference to a String
. This struct will allow for both searching and modifying the content of the String
.
The MutableTextFinder
struct should provide the following functionality:
new
: Creates a new instance of MutableTextFinder
with the given content.find_first
: Searches for the first line containing a given keyword and returns it as an immutable reference (Option<&str>
).replace_lines
: Replaces all lines containing a given keyword with a replacement string.get_text
: Returns the reference to the content.// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { MutableTextFinder { text } } pub fn find_first(&self, pat: &str) -> Option<&str> { self.text.lines().find(|&line| line.contains(pat)) } pub fn replace_lines(&mut self, pat: &str, replace: &'a str) { self.text .lines() .map(|line| if line.contains(pat) { replace } else { line }) .collect::<Vec<&str>>() .join("\n") .clone_into(self.text); } pub fn get_text(&self) -> &String { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> MutableTextFinder { Self { text } } pub fn find_first(&self, keyword: &str) -> Option<&str> { self.text.lines().find(|l| l.contains(keyword)) } pub fn replace_lines(&mut self, keyword: &str, replacement: &str) { self.text.lines() .map(|l| if l.contains(keyword) { replacement } else { l }) .collect::<Vec<&str>>() .join("\n") .clone_into(self.text) } pub fn get_text(&self) -> &String { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { Self { text, } } pub fn find_first(&self, keyword: &str) -> Option<&str> { self.text.lines().filter(|t| t.contains(&keyword)).next() } pub fn replace_lines(&mut self, search: &str, replace: &str) { self.text.lines() .map(|l| if l.contains(search) {replace} else {l}) .collect::<Vec<&str>>() .join("\n") .clone_into(self.text); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a>{ s: &'a mut String}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(s: &'a mut String) -> Self { Self{ s } } pub fn find_first(&self, s1: &str) -> Option<&str> { self.s.lines().find(|s| s.contains(s1)) } pub fn replace_lines(&mut self, search: &str, replace_lines: &'a str) { let new_line = self.s.split('\n') .map(|l| {if l.contains(search){ replace_lines} else { l }} ).collect::<Vec<&str>>(); *self.s = new_line.join("\n"); } pub fn get_text(&self) -> &str { self.s }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String,}impl <'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { MutableTextFinder { text } } pub fn find_first(&self, pattern: &str) -> Option<&str> { self.text.split('\n').find(|line| line.contains(pattern)) } pub fn replace_lines(&mut self, pattern: &str, replacement: &str) { let newtext = self.text.split('\n') .map(|line| if line.contains(pattern) { replacement } else { line }); *self.text = newtext.collect::<Vec<&str>>().join("\n"); } pub fn get_text(&self) -> &str { self.text } }// 2. Implement the methods for the struct// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a>{ text: &'a mut String}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a>{ pub fn new(text: &'a mut String)-> Self{ MutableTextFinder{text} } pub fn find_first(&self, text: &str)-> Option<&str>{ self.text.lines().find(|t| t.contains(text)) } pub fn replace_lines(&mut self,text1: &str, text2: &str){ *self.text=self.text.lines() .map(|ll| if ll.contains(text1){text2}else{ll}) .collect::<Vec<_>>() .join("\n"); } pub fn get_text(&self)->&String{ &self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { pub text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { MutableTextFinder { text } } pub fn find_first(&self, pattern: &str) -> Option<&str> { self.text.lines().find(|line| line.contains(pattern)) } pub fn replace_lines(&mut self, pattern: &str, replacement: &str) { *self.text = self .text .lines() .map(|line| { if line.contains(pattern) { replacement.to_string() } else { line.to_string() } }) .collect::<Vec<String>>() .join("\n"); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { s: &'a mut String}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(s: &'a mut String) -> Self { Self { s } } pub fn find_first(&self, keyword: &str) -> Option<&str>{ self.s.lines().find(|&l| l.contains(keyword)) } pub fn replace_lines(&mut self, keyword: &str, replacement: &str) { let new_str = self.s.lines().map(|l| { if l.contains(keyword) { replacement } else { l } }).collect::<Vec<&str>>() .join("\n"); self.s.clear(); self.s.push_str(&new_str); } pub fn get_text(&self) -> &String { self.s }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { Self { text } } pub fn find_first(&self, pattern: &str) -> Option<&str> { for l in self.text.lines() { if l.contains(pattern) { return Some(l); } } None } pub fn replace_lines(&mut self, pattern: &str, replacement: &str) { self.text.lines().map(|l| if l.contains(pattern) { replacement } else { l }).collect::<Vec<& str>>().join("\n").clone_into(self.text); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> MutableTextFinder<'a> { MutableTextFinder { text } } pub fn find_first(&self, keyword: &str) -> Option<&str> { self.text.lines().find(|line| line.contains(keyword)) } pub fn replace_lines(&mut self, keyword: &str, replacement: &str) { self.text .lines() .map(|line| { if line.contains(keyword) { replacement } else { line } }) .collect::<Vec<&str>>() .join("\n") .clone_into(self.text); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { pub text: &'a mut String}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(s: &'a mut String) -> Self { MutableTextFinder { text: s } } pub fn find_first(&self, keyword: &str) -> Option<&str> { return self.text.lines().find(|&s| s.contains(keyword)); } pub fn replace_lines(&mut self, keyword: &str, replacement: &str) { self.text.lines().map(|s| { if s.contains(keyword) { replacement } else { s } }).collect::<Vec<&str>>().join("\n").clone_into(self.text); //let index = self.text.find(keyword); //self.text.replace(index, keyword.len(), replacement); //self.text.replacen(keyword, replacement, 1); } pub fn get_text(&self) -> &str { return self.text; }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { pub s: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(s: &'a mut String) -> Self { Self { s } } pub fn find_first(&self, keyword: &str) -> Option<&str> { self.s.lines().find(|&x| { x.contains(keyword) }) } pub fn replace_lines(&mut self, keyword: &str, replacement: &str) { self.s.lines() .map(|x| { if x.contains(keyword) { replacement } else { x } }).collect::<Vec<&str>>() .join("\n") .clone_into(self.s); } pub fn get_text(&self) -> &str { self.s }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { text: &'a mut String}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { Self {text} } pub fn find_first(&self, key: &'a str) -> Option<&str> { self.text.split("\n").find(move |&x| x.contains(key)) } pub fn replace_lines(&mut self, key: &'a str, replace: &'a str) { self.text.lines().map(move |x| if x.contains(key) {format!("{}\n", replace)} else {format!("{}\n", x)}).collect::<String>().trim().clone_into(self.text) } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
pub struct MutableTextFinder<'a> { text: &'a mut String,}impl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { Self {text} } pub fn find_first(&self, slice: &str) -> Option<&str> { self.text.lines().find(|line| line.contains(slice)) } pub fn replace_lines(&mut self, keyword: &str, replacement: &str) { self.text.lines().map(|line| { if line.contains(keyword) { replacement } else { line } }) .collect::<Vec<_>>() .join("\n") .clone_into(self.text); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
pub struct MutableTextFinder<'a> { text: &'a mut String,}impl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { MutableTextFinder { text: text } } pub fn find_first(&self, keyword: &str) -> Option<&str> { self.text.lines().find(|x| x.contains(keyword)) } pub fn replace_lines(&mut self, keyword: &str, replace: &str) { self.text .lines() .map(|line| { if line.contains(keyword) { format!("{}\n", replace) } else { format!("{}\n", line) } }) .collect::<String>() .trim() .clone_into(self.text); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { content: &'a mut String}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &mut String) -> MutableTextFinder { MutableTextFinder{ content: text } } pub fn find_first(&self, search: &str) -> Option<&str> { self.content .lines() .find(|l| l.contains(search) ) } pub fn get_text(&self) -> &str { self.content } pub fn replace_lines(&mut self, find: &str, replace: &str) { let _ = self.content .lines() .map(|l| match l.contains(find) { true => format!("{}\n", replace), false => format!("{}\n", l) } ) .collect::<String>() .trim() .clone_into(self.content); }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { pub inner: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { Self { inner: text } } pub fn find_first(&self, search: &str) -> Option<&str> { self.inner.lines().find(|it| it.contains(search)) } pub fn replace_lines(&mut self, search: &str, replace: &str) { let modified = self .inner .lines() .map(|line| { if line.contains(search) { replace.to_string() } else { line.to_string() } }) .collect::<Vec<_>>() .join("\n"); self.inner.clear(); self.inner.push_str(&modified); } pub fn get_text(&self) -> &str { self.inner }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a> { pub text: &'a mut String,}// 2. Implement the methods for the structimpl<'a> MutableTextFinder<'a> { pub fn new(s: &'a mut String) -> Self { Self { text: s } } pub fn find_first(&self, keyword: &str) -> Option<&str> { self.text.lines().find(|l| l.contains(keyword)) } pub fn replace_lines(&mut self, before: &str, after: &str) { let modified: String = self.text .lines() .map(|l| { if l.contains(before) { after.to_string() } else { l.to_string() } }) .collect::<Vec<String>>() .join("\n"); self.text.clear(); self.text.push_str(&modified); } pub fn get_text(&self) -> &str { self.text }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}
// 1. Finish the struct definitionpub struct MutableTextFinder<'a>(&'a mut String);impl<'a> MutableTextFinder<'a> { pub fn new(text: &'a mut String) -> Self { Self(text) } pub fn get_text(&self) -> &String { self.0 } pub fn find_first(&self, text: &str) -> Option<&str> { let lines = self.0.split('\n').collect::<Vec<&str>>(); lines.iter().find(|line| line.contains(text)).map(move |line| *line) } pub fn replace_lines(&mut self, text: &str, replacement: &str) { // Split the original string into lines for x in self.0.lines() { } let lines: Vec<&str> = self.0.lines().collect(); // Iterate over the lines and replace lines containing the keyword let replaced_lines: Vec<String> = lines.iter() .map(|line| { if line.contains(text) { replacement.to_string() } else { line.to_string() } }) .collect(); self.0.clear(); self.0.push_str(&replaced_lines.join("\n")); // Join the lines back together // let mut a = replaced_lines.join("\n"); // self.0 = &a; } pub fn replace_all_occurrence(&mut self, text: &str, replacement: &str) { let index_diff = (replacement.len() - text.len()) as i32; let all_match = self.0.match_indices(text).map(|(x, _)| { x }).collect::<Vec<usize>>(); let mut diff = 0i32; for x in all_match { self.0.replace_range(((x as i32 + diff) as usize)..((x as i32 + diff) as usize + text.len()), replacement); diff += index_diff; } }}// Example usagepub fn main() { let mut text = String::from("Rust is awesome\nLearning Rust\nFun with Rustaceans"); let mut finder = MutableTextFinder::new(&mut text); let first = finder.find_first("Rust"); println!("{:?}", first); // Should print: Some("Rust is awesome") finder.replace_lines("Rust", "Programming in Rust"); println!("{}", finder.get_text()); // Should print the modified text}