MeiliSearch/meilisearch-http/src/routes/setting.rs

92 lines
2.7 KiB
Rust
Raw Normal View History

2019-12-12 19:10:47 +01:00
use serde::{Deserialize, Serialize, Deserializer};
2020-01-15 17:10:33 +01:00
use tide::{Request, Response};
2019-10-31 15:00:36 +01:00
use crate::error::{ResponseError, SResult};
2020-01-15 17:10:33 +01:00
use crate::helpers::tide::RequestExt;
2019-10-31 15:00:36 +01:00
use crate::models::token::ACL::*;
use crate::routes::document::IndexUpdateResponse;
use crate::Data;
2019-12-12 19:10:47 +01:00
#[derive(Default, Serialize, Deserialize)]
2019-10-31 15:00:36 +01:00
#[serde(rename_all = "camelCase", deny_unknown_fields)]
2019-12-12 19:10:47 +01:00
pub struct Setting {
2019-10-31 15:00:36 +01:00
pub distinct_field: Option<DistinctField>,
pub ranking_rules: Option<RankingRules>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RankingOrdering {
Asc,
Dsc,
}
pub type DistinctField = String;
2020-01-08 14:17:38 +01:00
pub type RankingRules = Vec<String>;
2019-10-31 15:00:36 +01:00
2020-01-15 17:10:33 +01:00
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
2019-10-31 15:00:36 +01:00
ctx.is_allowed(SettingsRead)?;
let index = ctx.index()?;
let db = &ctx.state().db;
2020-01-16 16:58:57 +01:00
let reader = db.main_read_txn()?;
2019-10-31 15:00:36 +01:00
let settings = match index.main.customs(&reader).unwrap() {
Some(bytes) => bincode::deserialize(bytes).unwrap(),
2019-12-12 19:10:47 +01:00
None => Setting::default(),
2019-10-31 15:00:36 +01:00
};
2020-01-15 17:10:33 +01:00
Ok(tide::Response::new(200).body_json(&settings).unwrap())
2019-10-31 15:00:36 +01:00
}
2019-12-12 19:10:47 +01:00
#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct SettingBody {
#[serde(default, deserialize_with = "deserialize_some")]
pub distinct_field: Option<Option<DistinctField>>,
#[serde(default, deserialize_with = "deserialize_some")]
pub ranking_rules: Option<Option<RankingRules>>,
}
// Any value that is present is considered Some value, including null.
fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
where T: Deserialize<'de>,
D: Deserializer<'de>
{
Deserialize::deserialize(deserializer).map(Some)
}
2020-01-15 17:10:33 +01:00
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
2019-10-31 15:00:36 +01:00
ctx.is_allowed(SettingsWrite)?;
let settings: SettingBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
let index = ctx.index()?;
let db = &ctx.state().db;
2020-01-16 16:58:57 +01:00
let reader = db.main_read_txn()?;
let mut writer = db.update_write_txn()?;
2019-10-31 15:00:36 +01:00
let mut current_settings = match index.main.customs(&reader).unwrap() {
2019-10-31 15:00:36 +01:00
Some(bytes) => bincode::deserialize(bytes).unwrap(),
2019-12-12 19:10:47 +01:00
None => Setting::default(),
2019-10-31 15:00:36 +01:00
};
if let Some(distinct_field) = settings.distinct_field {
2019-12-12 19:10:47 +01:00
current_settings.distinct_field = distinct_field;
2019-10-31 15:00:36 +01:00
}
if let Some(ranking_rules) = settings.ranking_rules {
2019-12-12 19:10:47 +01:00
current_settings.ranking_rules = ranking_rules;
2019-10-31 15:00:36 +01:00
}
let bytes = bincode::serialize(&current_settings).unwrap();
2020-01-16 16:58:57 +01:00
let update_id = index.customs_update(&mut writer, bytes)?;
2019-10-31 15:00:36 +01:00
2020-01-16 16:58:57 +01:00
writer.commit()?;
2019-10-31 15:00:36 +01:00
let response_body = IndexUpdateResponse { update_id };
2020-01-15 17:10:33 +01:00
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
2019-10-31 15:00:36 +01:00
}