diff options
Diffstat (limited to 'src/parse.rs')
-rw-r--r-- | src/parse.rs | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/src/parse.rs b/src/parse.rs new file mode 100644 index 0000000..a4cdc3c --- /dev/null +++ b/src/parse.rs @@ -0,0 +1,242 @@ + +use serde::{Serialize, Deserialize}; +use std::collections::HashMap; + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiRequest { + pub method: String, + pub path_and_query: String, + pub body: Option<SearchBody>, +} + +pub struct UrlQueryParams { + pub allow_no_indices: Option<bool>, + pub allow_partial_search_results: Option<bool>, + pub batched_reduce_size: Option<u32>, + pub ccs_minimize_roundtrips: Option<bool>, + pub docvalue_fields: Option<String>, // array of strings, comma-separated + pub expand_wildcards: Option<String>, + pub explain: Option<bool>, + pub from: Option<u32>, + pub ignore_throttled: Option<bool>, + pub ignore_unavailable: Option<bool>, + pub max_concurrent_shard_requests: Option<u32>, + pub pre_filter_shard_size: Option<u32>, + pub preference: Option<String>, + pub q: Option<String>, + pub request_cache: Option<bool>, + pub rest_total_hits_as_int: Option<bool>, + pub routing: Option<String>, + pub scroll: Option<String>, // string is "time value" + pub search_type: Option<String>, + pub seq_no_primary_term: Option<bool>, + pub size: Option<u32>, + pub sort: Option<String>, // array of strings, comma-separated + pub _source: Option<bool>, // TODO: bool or string + pub _source_excludes: Option<String>, // array of strings, comma-separated + pub _source_includes: Option<String>, // array of strings, comma-separated + pub stats: Option<String>, + pub stored_fields: Option<String>, // array of strings, comma-separated + pub suggest_field: Option<String>, + pub suggest_text: Option<String>, + pub terminate_after: Option<u32>, + pub timeout: Option<String>, // string is "time units" + pub track_scores: Option<bool>, + pub track_total_hits: Option<bool>, // XXX: bool or integer + pub typed_keys: Option<bool>, + pub version: Option<bool>, +} + +// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html +#[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] +pub struct SearchBody { + pub query: Option<ApiQuery>, + pub highlight: Option<ApiHighlight>, + pub collapse: Option<ApiCollapse>, + pub post_filter: Option<ApiQuery>, // TODO: leaf query only? + pub rescore: Option<ApiRescore>, // TODO: single or an array of rescore objects + // script_fields disabled + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html + pub sort: Option<Vec<SortElement>>, + + pub slice: Option<ApiSlice>, + pub stored_fields: Option<String>, // array of strings, or "_none_" + + // overlap with URL query parameters + pub docvalue_fields: Option<Vec<DocValOrString>>, + pub explain: Option<bool>, + pub from: Option<u32>, + pub min_score: Option<f64>, + pub seq_no_primary_term: Option<bool>, + pub size: Option<u32>, + pub _source: Option<bool>, // XXX: bool, string, or object + pub terminate_after: Option<u32>, + pub timeout: Option<String>, // string is "time units" +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] +pub struct ScrollBody { + pub scroll_id: String, + pub scroll: Option<String>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiSlice { + id: u32, + max: u32, + field: Option<String>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiRescore{ + pub query: Option<ApiQuery>, + pub window_size: Option<u32>, +} + +// TODO: could revert to having query types as an enum, with flattening +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiQuery { + // compound queries + #[serde(rename = "bool")] + bool_query: Option<BoolQuery>, + boosting: Option<BoostingQuery>, + constant_score: Option<ConstantScoreQuery>, + + // fulltext (leaf) queries + + // term-level (leaf) queries + #[serde(rename = "match")] + match_query: Option<HashMap<String, QueryFieldOrString>>, + match_phrase: Option<HashMap<String, QueryFieldOrString>>, + query_string: Option<QueryField>, + + // other + nested: Option<NestedQuery>, + rescore_query: Option<Box<ApiQuery>>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiHighlight{ + // TODO: fields could also be an array of strings? + fields: HashMap<String, HighlightField>, + + #[serde(flatten)] + settings: HighlightField, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum SortMapValue { + String(String), + Object { order: String, mode: Option<String> }, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum SortElement{ + String(String), + Object(HashMap<String, SortMapValue>), +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum DocValOrString { + String(String), + Object {field: String, format: Option<String>}, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum QueryFieldOrString { + Object(QueryField), + String(String), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct QueryField{ + query: String, + fuzziness: Option<String>, + slop: Option<u32>, + boost: Option<f64>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct BoolQuery { + must: Option<Box<ApiQuery>>, + filter: Option<Box<ApiQuery>>, + should: Option<Box<ApiQuery>>, + must_not: Option<Box<ApiQuery>>, + minimum_should_match: Option<u32>, + boost: Option<f64>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct NestedQuery { + path: String, + query: Box<ApiQuery>, + score_mode: Option<String>, + ignore_unmapped: Option<bool>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct BoostingQuery { + positive: Box<ApiQuery>, + negative: Box<ApiQuery>, + negative_boost: f64, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConstantScoreQuery { + filter: Box<ApiQuery>, + boost: Option<f64>, +} + +// https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html +#[derive(Serialize, Deserialize, Debug)] +pub struct HighlightField{ + boundary_chars: Option<String>, + boundary_max_scan: Option<u32>, + boundary_scanner: Option<String>, + boundary_scanner_locale: Option<String>, + encoder: Option<String>, + force_source: Option<bool>, + fragmenter: Option<String>, + fragment_offset: Option<u32>, + fragment_size: Option<u32>, + highlight_query: Option<ApiQuery>, + matched_fields: Option<Vec<String>>, + no_match_size: Option<u32>, + number_of_fragments: Option<u32>, + order: Option<String>, + phrase_limit: Option<u32>, + pre_tags: Option<Vec<String>>, + post_tags: Option<Vec<String>>, + require_field_match: Option<bool>, + tags_schema: Option<String>, + #[serde(rename = "type")] + highlight_type: Option<String>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiCollapse{ + field: String, + inner_hits: Option<InnerHitsOneOrMore>, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum InnerHitsOneOrMore { + Single(InnerHits), + Multiple(Vec<InnerHits>), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct InnerHits { + from: Option<u32>, + size: Option<u32>, + sort: Option<Vec<SortElement>>, + name: Option<String>, +} |