diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 243 | ||||
| -rw-r--r-- | src/parse.rs | 242 | 
2 files changed, 244 insertions, 241 deletions
| @@ -1,9 +1,9 @@ +use serde::{Serialize, Deserialize};  use hyper::{Request, Body, Method, Uri};  use http::request; -use serde::{Serialize, Deserialize}; -use std::collections::HashMap; +pub mod parse;  #[derive(Default, Deserialize, Debug, Clone)]  pub struct ProxyConfig { @@ -29,245 +29,6 @@ impl ProxyConfig {      }  } -#[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>, -} -  #[derive(Debug)]  pub enum ParsedRequest {      Malformed(String), 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>, +} | 
