use std::{
fs::File,
io::{self, BufRead},
path::Path,
};
pub fn head(path: &Path, n: usize) -> Vec<String> {
let file = File::open(path).unwrap();
let lines = io::BufReader::new(file).lines();
lines.take(n).map(|f| f.unwrap()).collect()
}
fn get_line_count(path: &Path) -> usize {
let file = File::open(path).unwrap();
let lines = io::BufReader::new(file).lines();
lines.count()
}
pub fn tail(path: &Path, n: usize) -> Vec<String> {
let total = get_line_count(path);
let file = File::open(path).unwrap();
let lines = io::BufReader::new(file).lines();
lines
.skip(total.saturating_sub(n))
.map(|f| f.unwrap())
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_head_panic() {
let _res = head(Path::new("abc"), 1usize);
}
#[test]
#[should_panic]
fn test_tail_panic() {
let _res = tail(Path::new("abc"), 1usize);
}
#[test]
fn test_head() {
let res = head(Path::new("./test_files/test_file.txt"), 2usize);
assert_eq!(res, vec!["Hello".to_string(), "Hello, World!".to_string()]);
}
#[test]
fn test_tail() {
let res = tail(Path::new("./test_files/test_file.txt"), 3usize);
assert_eq!(
res,
vec!["abc".to_string(), "def".to_string(), "xyz".to_string()]
);
}
}