summaryrefslogtreecommitdiffstats
path: root/src/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse.rs')
-rw-r--r--src/parse.rs242
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>,
+}