memplace 0.1.0

command and snippet manager
use serde::{Deserialize, Serialize};
use std::error::Error;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::path::Path;
use std::vec;
use strsim::levenshtein;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Post {
    pub id: usize,
    pub command: String,
    pub comment: String,
}
impl Post {
    pub fn new(id: usize, command: String, comment: String) -> Self {
        Self {
            id,
            command,
            comment,
        }
    }
}
pub fn write_it(filename: &str, post: &Vec<Post>) -> Result<(), Box<dyn Error>> {
    let file = File::create(filename)?;
    let writer = BufWriter::new(file);
    serde_json::to_writer_pretty(writer, post)?;
    Ok(())
}
pub fn read_it(filename: &str) -> Result<Vec<Post>, Box<dyn Error>> {
    if !Path::new(filename).exists() {
        return Ok(Vec::new());
    }
    let file = File::open(filename)?;
    let reader = BufReader::new(file);
    let posts = serde_json::from_reader(reader)?;
    Ok(posts)
}
pub fn create_it(
    command: String,
    comment: String,
    posts: &mut Vec<Post>,
) -> Result<(), Box<dyn Error>> {
    let last_id = match posts.last() {
        Some(value) => value.id + 1,
        None => 0,
    };
    let post = Post::new(last_id, command, comment);
    posts.push(post);
    Ok(())
}
// pub fn search_it(needle: &str, haystack: &Vec<Post>) {
pub fn search_it<'a>(needle: &str, haystack: &'a [Post]) -> Vec<&'a Post> {
    if needle.is_empty() {
        return Vec::new();
    }
    let nedl = needle.to_lowercase();
    let mut scoreboard: Vec<(usize, usize)> = vec![];
    let mut sorted_matches: Vec<&Post> = vec![];
    for (index, post) in haystack.iter().enumerate() {
        let hay: Vec<char> = format!("{}{}", post.command, post.comment)
            .to_lowercase()
            .chars()
            .collect();
        // let hay: Vec<char> = fhay.chars().collect();
        let mut score: usize = nedl.chars().count();
        for window in hay.windows(needle.len()) {
            let wind: String = window.iter().collect();
            let cscore = levenshtein(&nedl, &wind);
            if cscore < score {
                score = cscore;
            }
        }

        scoreboard.push((score, index));
    }
    scoreboard.sort_by_key(|t| t.0);
    for scores in scoreboard {
        sorted_matches.push(&haystack[scores.1]);
    }
    sorted_matches
    // check(&sorted_matches, needle).unwrap();
}