summaryrefslogblamecommitdiff
path: root/angelsharkd/src/routes/extensions/simple_search.rs
blob: 7b547d3877b8681740dbd6d3205428984b1b7636 (plain) (tree)
1
2
3
4
5
6
7
8
9
                             



                        



                                              
 

                              
 

                                                                                                   



                                             

                                                                              

 



                                                                   

                               
                                                                           

 

                                                                                              

 

                                                                                                  
                           

 
                                                                         

                     
                              

 
               
                          





                                                                  




                                                



                                       
                                 
                                                                 
 

                                                  

                                     

           
 
use libangelshark::AcmRunner;
use std::{
    convert::Infallible,
    sync::{Arc, Mutex},
};
use warp::{
    body::{content_length_limit, json},
    get, path, post, Filter, Rejection, Reply,
};

/// Collection of search terms
type Needle = Vec<String>;

pub fn search(haystack: Haystack) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
    // TODO: discourage caching response thru headers

    path("search")
        .and(post())
        .and(content_length_limit(1024 * 16))
        .and(json())
        .and_then(move |terms: Needle| handle_search(haystack.clone(), terms))
}

pub fn refresh(
    runner: AcmRunner,
    haystack: Haystack,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
    path!("search" / "refresh")
        .and(get())
        .and_then(move || handle_refresh(haystack.clone(), runner.clone()))
}

async fn handle_search(haystack: Haystack, needle: Needle) -> Result<impl Reply, Infallible> {
    Ok(haystack.search(Vec::new()))
}

async fn handle_refresh(haystack: Haystack, runner: AcmRunner) -> Result<impl Reply, Infallible> {
    haystack.refresh();
    Ok("Refresh scheduled")
}

/// A lazy-loaded, asynchronously-refreshed exension-type haystack cache.
#[derive(Clone)]
pub struct Haystack {
    inner: Arc<Mutex<String>>,
}

impl Haystack {
    pub fn new() -> Self {
        Self {
            inner: Arc::new(Mutex::new(String::with_capacity(0))),
        }
    }

    pub fn search(&self, needle: Needle) -> String {
        if let Ok(matches) = self.inner.lock() {
            matches.clone()
        } else {
            String::from("stale")
        }
    }

    pub fn refresh(&self) {
        let inner = self.inner.clone();
        tokio::spawn(async move {
            std::thread::sleep_ms(10000); // slow generation here

            if let Ok(mut handle) = inner.lock() {
                *handle = String::from("fresh");
                eprintln!("evicted");
            }
        });
    }
}