Files
pages/src/search/mod.rs
Valentin Ricard 7a6ecd86c6 Rewrite the app (#23)
* chore: Removed everything not needed, and added base for rewrite
feat(error_handling): Added 404 general cache
feat(index): Added informations about the app in the / route.

* feat(indexing): Brought back the indexing, with conditions to make it easier

* fix: Fixed build error with a forgotten call

* feat: Add Docker development enviroment (#19)

* ci: add a *lot* of new actions

* fix: rename linting action

* fix: invalid yaml begone(?)

* ci: Added cache to speed up build times

* fix(ci): 🦀ed the yaml errors

* fix(ci): fixed a missing hyphen

* ci: Added matrix of rust versions, and changed way to install rust toolchain

* fix(ci): Added names to build with the matrix so it's easier to find the source of the problem

* style(ci): Added eof lines

* refactor: Finished moving the search.rs file to a separate module.

* Search Endpoint

* refactor: Moved around functions and struct for a better understanding of what it does.

* chore: Change env default settings to resolve conversation

* refactor: Removed #[use_macros]
fix: Fixed meilisearch address from env

* chore: Added email to Aeledfyr

* fix: Brought back the dotenv variables

* style: Ran `cargo fmt`

Co-authored-by: Charalampos Fanoulis <charalampos.fanoulis@gmail.com>
Co-authored-by: Jai A <jai.a@tuta.io>
2020-06-30 19:23:52 +02:00

106 lines
2.8 KiB
Rust

use crate::database::DatabaseError;
use crate::models::mods::SearchRequest;
use meilisearch_sdk::client::Client;
use meilisearch_sdk::document::Document;
use meilisearch_sdk::search::Query;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub mod indexing;
#[derive(Error, Debug)]
pub enum SearchError {
#[error("Error while connection to the MeiliSearch database")]
IndexDBError(),
#[error("Error while connecting to the local server")]
LocalDatabaseError(#[from] mongodb::error::Error),
#[error("Error while accessing the data from remote")]
RemoteWebsiteError(#[from] reqwest::Error),
#[error("Error while serializing or deserializing JSON")]
SerDeError(#[from] serde_json::Error),
#[error("Error while parsing float")]
FloatParsingError(#[from] std::num::ParseFloatError),
#[error("Error while parsing float")]
IntParsingError(#[from] std::num::ParseIntError),
#[error("Error while parsing BSON")]
DatabaseError(#[from] DatabaseError),
#[error("Environment Error")]
EnvError(#[from] dotenv::Error),
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SearchMod {
pub mod_id: i32,
pub author: String,
pub title: String,
pub description: String,
pub keywords: Vec<String>,
pub versions: Vec<String>,
pub downloads: i32,
pub page_url: String,
pub icon_url: String,
pub author_url: String,
pub date_created: String,
pub created: i64,
pub date_modified: String,
pub updated: i64,
pub latest_version: String,
pub empty: String,
}
impl Document for SearchMod {
type UIDType = i32;
fn get_uid(&self) -> &Self::UIDType {
&self.mod_id
}
}
pub fn search_for_mod(info: &SearchRequest) -> Result<Vec<SearchMod>, SearchError> {
let address = &*dotenv::var("MEILISEARCH_ADDR")?;
let client = Client::new(address, "");
let search_query: &str;
let mut filters = String::new();
let mut offset = 0;
let mut index = "relevance";
match info.query.as_ref() {
Some(q) => search_query = q,
None => search_query = "{}{}{}",
}
if let Some(f) = info.filters.as_ref() {
filters = f.clone();
}
if let Some(v) = info.version.as_ref() {
if filters.is_empty() {
filters = v.clone();
} else {
filters = format!("({}) AND ({})", filters, v);
}
}
if let Some(o) = info.offset.as_ref() {
offset = o.parse().unwrap();
}
if let Some(s) = info.index.as_ref() {
index = s;
}
let mut query = Query::new(search_query).with_limit(10).with_offset(offset);
if !filters.is_empty() {
query = query.with_filters(&filters);
}
Ok(client
.get_index(format!("{}_mods", index).as_ref())
.unwrap()
.search::<SearchMod>(&query)
.unwrap()
.hits)
}