diff options
author | Bryan Newbold <bnewbold@archive.org> | 2020-08-25 18:59:34 -0700 |
---|---|---|
committer | Bryan Newbold <bnewbold@archive.org> | 2020-08-25 18:59:34 -0700 |
commit | 52c8213c0889f0ff16ff48c83121fb41bad56ba7 (patch) | |
tree | 14d1ae8d8f9ccc6f019b788bb97d48a949d93e32 /src | |
parent | 2f9054309e3d12be5b9d9be56c09e935c0bc0c06 (diff) | |
download | es-public-proxy-52c8213c0889f0ff16ff48c83121fb41bad56ba7.tar.gz es-public-proxy-52c8213c0889f0ff16ff48c83121fb41bad56ba7.zip |
fmt
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 95 | ||||
-rw-r--r-- | src/main.rs | 38 | ||||
-rw-r--r-- | src/parse.rs | 435 |
3 files changed, 297 insertions, 271 deletions
@@ -1,6 +1,5 @@ - +use hyper::{Body, Method, Request, Uri}; use serde::Deserialize; -use hyper::{Request, Body, Method, Uri}; use serde_json::json; pub mod parse; @@ -9,10 +8,10 @@ use parse::UrlQueryParams; #[derive(Default, Deserialize, Debug, Clone)] pub struct ProxyConfig { - pub bind_addr: Option<String>, // 127.0.0.1:9292 - pub upstream_addr: Option<String>, // 127.0.0.1:9200 + pub bind_addr: Option<String>, // 127.0.0.1:9292 + pub upstream_addr: Option<String>, // 127.0.0.1:9200 pub allow_all_indices: Option<bool>, - pub index: Vec<IndexConfig> + pub index: Vec<IndexConfig>, } #[derive(Deserialize, Debug, Clone)] @@ -21,14 +20,13 @@ pub struct IndexConfig { } impl ProxyConfig { - pub fn allow_index(&self, name: &str) -> bool { if self.allow_all_indices == Some(true) { - return true + return true; } for index in &self.index { if index.name == name { - return true + return true; } } false @@ -45,7 +43,6 @@ pub enum ProxyError { } impl ProxyError { - pub fn to_json(&self) -> serde_json::Value { json!({ "error": { @@ -57,7 +54,10 @@ impl ProxyError { } } -pub async fn filter_request(req: Request<Body>, config: &ProxyConfig) -> Result<Request<Body>, ProxyError> { +pub async fn filter_request( + req: Request<Body>, + config: &ProxyConfig, +) -> Result<Request<Body>, ProxyError> { let (parts, body) = req.into_parts(); // split path into at most 3 chunks @@ -67,7 +67,9 @@ pub async fn filter_request(req: Request<Body>, config: &ProxyConfig) -> Result< } let path_chunks: Vec<&str> = req_path.split("/").collect(); if path_chunks.len() > 3 { - return Err(ProxyError::NotSupported("only request paths with up to three segments allowed".to_string())) + return Err(ProxyError::NotSupported( + "only request paths with up to three segments allowed".to_string(), + )); } let params: UrlQueryParams = serde_urlencoded::from_str(parts.uri.query().unwrap_or("")) @@ -75,30 +77,28 @@ pub async fn filter_request(req: Request<Body>, config: &ProxyConfig) -> Result< // this is sort of like a router let body = match (&parts.method, path_chunks.as_slice()) { - (&Method::GET, [""]) | (&Method::HEAD, [""]) => { - Body::empty() - }, + (&Method::GET, [""]) | (&Method::HEAD, [""]) => Body::empty(), (&Method::POST, ["_search", "scroll"]) | (&Method::DELETE, ["_search", "scroll"]) => { let whole_body = hyper::body::to_bytes(body) .await .map_err(|e| ProxyError::Malformed(e.to_string()))?; filter_scroll_request(¶ms, &whole_body, config)? - }, + } (&Method::GET, [index, "_search"]) | (&Method::POST, [index, "_search"]) => { let whole_body = hyper::body::to_bytes(body) .await .map_err(|e| ProxyError::Malformed(e.to_string()))?; filter_search_request(index, ¶ms, &whole_body, config)? - }, + } (&Method::GET, [index, "_count"]) | (&Method::POST, [index, "_count"]) => { let whole_body = hyper::body::to_bytes(body) .await .map_err(|e| ProxyError::Malformed(e.to_string()))?; filter_search_request(index, ¶ms, &whole_body, config)? - }, + } (&Method::GET, [index, "_doc", key]) | (&Method::GET, [index, "_source", key]) => { filter_read_request(index, path_chunks[1], key, ¶ms, config)? - }, + } _ => Err(ProxyError::NotSupported("unknown endpoint".to_string()))?, }; @@ -110,7 +110,13 @@ pub async fn filter_request(req: Request<Body>, config: &ProxyConfig) -> Result< }; let upstream_uri = Uri::builder() .scheme("http") - .authority(config.upstream_addr.as_ref().unwrap_or(&"localhost:9200".to_string()).as_str()) + .authority( + config + .upstream_addr + .as_ref() + .unwrap_or(&"localhost:9200".to_string()) + .as_str(), + ) .path_and_query(upstream_query_and_params.as_str()) .build() .expect("constructing upstream request URI"); @@ -123,21 +129,31 @@ pub async fn filter_request(req: Request<Body>, config: &ProxyConfig) -> Result< Ok(upstream_req) } -pub fn filter_scroll_request(_params: &UrlQueryParams, body: &[u8], _config: &ProxyConfig) -> Result<Body, ProxyError> { +pub fn filter_scroll_request( + _params: &UrlQueryParams, + body: &[u8], + _config: &ProxyConfig, +) -> Result<Body, ProxyError> { if body.len() > 0 { - let parsed: parse::ScrollBody = serde_json::from_slice(body) - .map_err(|e| ProxyError::ParseError(e.to_string()))?; + let parsed: parse::ScrollBody = + serde_json::from_slice(body).map_err(|e| ProxyError::ParseError(e.to_string()))?; // check that scroll_id is not "_all" or too short match &parsed.scroll_id { parse::StringOrArray::String(single) => { if single == "_all" || single.len() < 8 { - return Err(ProxyError::NotSupported(format!("short scroll_id: {}", single))); + return Err(ProxyError::NotSupported(format!( + "short scroll_id: {}", + single + ))); } - }, + } parse::StringOrArray::Array(array) => { for single in array { if single == "_all" || single.len() < 8 { - return Err(ProxyError::NotSupported(format!("short scroll_id: {}", single))); + return Err(ProxyError::NotSupported(format!( + "short scroll_id: {}", + single + ))); } } } @@ -148,21 +164,38 @@ pub fn filter_scroll_request(_params: &UrlQueryParams, body: &[u8], _config: &Pr } } -pub fn filter_read_request(index: &str, _endpoint: &str, _key: &str, _params: &UrlQueryParams, config: &ProxyConfig) -> Result<Body, ProxyError>{ +pub fn filter_read_request( + index: &str, + _endpoint: &str, + _key: &str, + _params: &UrlQueryParams, + config: &ProxyConfig, +) -> Result<Body, ProxyError> { if !config.allow_index(index) { - return Err(ProxyError::NotAllowed(format!("index doesn't exist or isn't proxied: {}", index))); + return Err(ProxyError::NotAllowed(format!( + "index doesn't exist or isn't proxied: {}", + index + ))); } Ok(Body::empty()) } -pub fn filter_search_request(index: &str, _params: &UrlQueryParams, body: &[u8], config: &ProxyConfig) -> Result<Body, ProxyError> { +pub fn filter_search_request( + index: &str, + _params: &UrlQueryParams, + body: &[u8], + config: &ProxyConfig, +) -> Result<Body, ProxyError> { if !config.allow_index(index) { - return Err(ProxyError::NotAllowed(format!("index doesn't exist or isn't proxied: {}", index))); + return Err(ProxyError::NotAllowed(format!( + "index doesn't exist or isn't proxied: {}", + index + ))); } // XXX: more checks if body.len() > 0 { - let parsed: parse::SearchBody = serde_json::from_slice(body) - .map_err(|e| ProxyError::ParseError(e.to_string()))?; + let parsed: parse::SearchBody = + serde_json::from_slice(body).map_err(|e| ProxyError::ParseError(e.to_string()))?; Ok(Body::from(serde_json::to_string(&parsed).unwrap())) } else { Ok(Body::empty()) diff --git a/src/main.rs b/src/main.rs index 2b25f32..0250976 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,15 @@ - use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Client, Request, Response, Server, StatusCode}; -use std::net::SocketAddr; use std::env; +use std::net::SocketAddr; use toml; -use es_public_proxy::{ProxyConfig, filter_request}; +use es_public_proxy::{filter_request, ProxyConfig}; -async fn upstream_req(req: Request<Body>, config: ProxyConfig) -> Result<Response<Body>, hyper::Error> { +async fn upstream_req( + req: Request<Body>, + config: ProxyConfig, +) -> Result<Response<Body>, hyper::Error> { println!("hit: {}", req.uri()); let parsed = filter_request(req, &config).await; let resp = match parsed { @@ -15,13 +17,11 @@ async fn upstream_req(req: Request<Body>, config: ProxyConfig) -> Result<Respons println!("sending request..."); Client::new().request(upstream_req).await? } - Err(other) => { - Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .header("Content-Type", "application/json; charset=UTF-8") - .body(serde_json::to_string(&other.to_json()).unwrap().into()) - .unwrap() - }, + Err(other) => Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .header("Content-Type", "application/json; charset=UTF-8") + .body(serde_json::to_string(&other.to_json()).unwrap().into()) + .unwrap(), }; println!("resp!"); Ok(resp) @@ -35,7 +35,6 @@ async fn shutdown_signal() { } async fn run_server(config: ProxyConfig) { - let addr = match &config.bind_addr { None => SocketAddr::from(([127, 0, 0, 1], 9292)), Some(addr) => addr.parse().unwrap(), @@ -46,11 +45,7 @@ async fn run_server(config: ProxyConfig) { // TODO: possible to avoid cloning config on every connection? let make_svc = make_service_fn(move |_| { let inner = config.clone(); - async move { - Ok::<_, hyper::Error>(service_fn(move |req| { - upstream_req(req, inner.clone()) - })) - } + async move { Ok::<_, hyper::Error>(service_fn(move |req| upstream_req(req, inner.clone()))) } }); let serve_future = Server::bind(&addr).serve(make_svc); let graceful = serve_future.with_graceful_shutdown(shutdown_signal()); @@ -65,7 +60,6 @@ fn usage() -> String { } fn load_config() -> ProxyConfig { - let args: Vec<String> = env::args().collect(); let args: Vec<&str> = args.iter().map(|x| x.as_str()).collect(); let mut config_path: Option<String> = None; @@ -73,13 +67,13 @@ fn load_config() -> ProxyConfig { // first parse CLI arg match args.as_slice() { - [_] | [] => {}, + [_] | [] => {} [_, "-h"] | [_, "--help"] => { println!("{}", usage()); std::process::exit(0); - }, - [_, "--config", p] => { config_path = Some(p.to_string()) }, - [_, "--allow-all-indices"] => { allow_all_indices = true }, + } + [_, "--config", p] => config_path = Some(p.to_string()), + [_, "--allow-all-indices"] => allow_all_indices = true, _ => { eprintln!("{}", usage()); eprintln!("couldn't parse arguments"); diff --git a/src/parse.rs b/src/parse.rs index 2a4c0a5..338ec64 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,5 +1,4 @@ - -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Serialize, Deserialize, Debug)] @@ -12,85 +11,85 @@ pub struct ApiRequest { #[derive(Serialize, Deserialize, Debug, Default)] #[serde(deny_unknown_fields)] pub struct UrlQueryParams { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub allow_no_indices: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub allow_partial_search_results: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub batched_reduce_size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub ccs_minimize_roundtrips: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub docvalue_fields: Option<String>, // array of strings, comma-separated - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub expand_wildcards: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub explain: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub from: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub ignore_throttled: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub ignore_unavailable: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub max_concurrent_shard_requests: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub pre_filter_shard_size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub preference: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub q: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub request_cache: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub rest_total_hits_as_int: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub routing: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub scroll: Option<String>, // string is "time value" - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub search_type: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub seq_no_primary_term: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub sort: Option<String>, // array of strings, comma-separated - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub _source: Option<bool>, // TODO: bool or string - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub _source_excludes: Option<String>, // array of strings, comma-separated - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub _source_includes: Option<String>, // array of strings, comma-separated - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub stats: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub stored_fields: Option<String>, // array of strings, comma-separated - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub suggest_field: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub suggest_text: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub terminate_after: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub timeout: Option<String>, // string is "time units" - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub track_scores: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub track_total_hits: Option<bool>, // XXX: bool or integer - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub typed_keys: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub version: Option<bool>, // additional generic params - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub human: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub pretty: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub filter_path: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub error_trace: Option<bool>, } @@ -98,49 +97,49 @@ pub struct UrlQueryParams { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct SearchBody { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub query: Option<ApiQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub highlight: Option<ApiHighlight>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub collapse: Option<ApiCollapse>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub post_filter: Option<ApiQuery>, // TODO: leaf query only? - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub rescore: Option<ApiRescore>, // TODO: single or an array of rescore objects // script_fields disabled - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub aggs: Option<HashMap<String, ApiAggregation>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub aggregations: Option<HashMap<String, ApiAggregation>>, // https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub sort: Option<Vec<SortElement>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub slice: Option<ApiSlice>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub stored_fields: Option<String>, // array of strings, or "_none_" // overlap with URL query parameters - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub docvalue_fields: Option<Vec<DocValOrString>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub explain: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub from: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub min_score: Option<Num>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub seq_no_primary_term: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub _source: Option<bool>, // XXX: bool, string, or object - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub terminate_after: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub timeout: Option<String>, // string is "time units" } @@ -148,7 +147,7 @@ pub struct SearchBody { #[serde(deny_unknown_fields)] pub struct ScrollBody { pub scroll_id: StringOrArray, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub scroll: Option<String>, } @@ -157,16 +156,16 @@ pub struct ScrollBody { pub struct ApiSlice { id: u32, max: u32, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] field: Option<String>, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct ApiRescore{ - #[serde(skip_serializing_if="Option::is_none")] +pub struct ApiRescore { + #[serde(skip_serializing_if = "Option::is_none")] pub query: Option<ApiQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pub window_size: Option<u32>, } @@ -176,65 +175,65 @@ pub struct ApiRescore{ pub struct ApiQuery { // compound queries #[serde(rename = "bool")] - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] bool_query: Option<BoolQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boosting: Option<BoostingQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] constant_score: Option<ConstantScoreQuery>, // fulltext (leaf) queries #[serde(rename = "match")] - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] match_query: Option<HashMap<String, MatchQueryOrString>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] match_phrase: Option<HashMap<String, QueryFieldOrString>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] multi_match: Option<MultiMatchQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] query_string: Option<QueryStringQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] simple_query_string: Option<QueryStringQuery>, // term-level (leaf) queries - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] exists: Option<SimpleFieldOrString>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] match_all: Option<SimpleBoost>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] match_none: Option<SimpleBoost>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] ids: Option<IdsQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] wildcard: Option<HashMap<String, TermQueryOrString>>, // also works for wildcard - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] prefix: Option<HashMap<String, TermQueryOrString>>, // also works for prefix query - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] range: Option<HashMap<String, RangeQuery>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] term: Option<HashMap<String, TermQueryOrString>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] // TODO: boost in terms query terms: Option<HashMap<String, Vec<String>>>, // other - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] nested: Option<NestedQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] rescore_query: Option<Box<ApiQuery>>, // fields as part of a rescore query - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] score_mode: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] query_weight: Option<Num>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] rescore_query_weight: Option<Num>, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct ApiHighlight{ +pub struct ApiHighlight { // TODO: fields could also be an array of strings? fields: HashMap<String, HighlightField>, @@ -249,7 +248,7 @@ pub enum SortMapValue { String(String), Object { order: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] mode: Option<String>, }, } @@ -257,7 +256,7 @@ pub enum SortMapValue { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] #[serde(untagged)] -pub enum SortElement{ +pub enum SortElement { String(String), Object(HashMap<String, SortMapValue>), } @@ -269,7 +268,7 @@ pub enum DocValOrString { String(String), Object { field: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] format: Option<String>, }, } @@ -298,10 +297,10 @@ pub struct MatchQuery { pub struct MultiMatchQuery { query: String, fields: Vec<String>, - #[serde(skip_serializing_if="Option::is_none")] - #[serde(rename="type")] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "type")] query_type: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] tie_breaker: Option<Num>, #[serde(flatten)] options: MatchOptions, @@ -310,27 +309,27 @@ pub struct MultiMatchQuery { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct MatchOptions { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] analyzer: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] auto_generate_synonyms_phrase_query: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzziness: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] max_expansions: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] prefix_length: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzzy_transpositions: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzzy_rewrite: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] lenient: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] operator: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] minimum_should_match: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] zero_terms_query: Option<String>, } @@ -339,57 +338,57 @@ pub struct MatchOptions { #[serde(deny_unknown_fields)] pub struct QueryStringQuery { query: String, - #[serde(skip_serializing_if="Option::is_none")] - #[serde(rename="type")] + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "type")] query_type: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] default_field: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] allow_leading_wildcard: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] analyze_wildcard: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] analyzer: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] auto_generate_synonyms_phrase_query: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] default_operator: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] enable_position_increments: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fields: Option<Vec<String>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzziness: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzzy_max_expansions: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzzy_prefix_length: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzzy_transpositions: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] lenient: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] max_determinized_states: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] minimum_should_match: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] quote_analyzer: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] phrase_slop: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] quote_field_suffix: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] rewrite: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] time_zone: Option<String>, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct SimpleBoost { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, } @@ -411,9 +410,9 @@ pub enum TermQueryOrString { #[serde(deny_unknown_fields)] pub struct TermQuery { value: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] rewrite: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, } @@ -445,21 +444,21 @@ pub enum StringOrArray { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct RangeQuery { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] gt: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] gte: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] lt: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] lte: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] format: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] relation: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] timezone: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, } @@ -473,30 +472,30 @@ pub enum QueryFieldOrString { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct QueryField{ +pub struct QueryField { query: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fuzziness: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] slop: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct BoolQuery { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] must: Option<Box<ApiQuery>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] filter: Option<Box<ApiQuery>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] should: Option<Box<ApiQuery>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] must_not: Option<Box<ApiQuery>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] minimum_should_match: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, } @@ -505,11 +504,11 @@ pub struct BoolQuery { pub struct NestedQuery { path: String, query: Box<ApiQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] score_mode: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] ignore_unmapped: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] inner_hits: Option<InnerHitsOneOrMore>, } @@ -525,54 +524,54 @@ pub struct BoostingQuery { #[serde(deny_unknown_fields)] pub struct ConstantScoreQuery { filter: Box<ApiQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boost: Option<Num>, } // https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct HighlightField{ - #[serde(skip_serializing_if="Option::is_none")] +pub struct HighlightField { + #[serde(skip_serializing_if = "Option::is_none")] boundary_chars: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boundary_max_scan: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boundary_scanner: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] boundary_scanner_locale: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] encoder: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] force_source: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fragmenter: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fragment_offset: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fragment_size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] highlight_query: Option<ApiQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] matched_fields: Option<Vec<String>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] no_match_size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] number_of_fragments: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] order: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] phrase_limit: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] pre_tags: Option<Vec<String>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] post_tags: Option<Vec<String>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] require_field_match: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] tags_schema: Option<String>, #[serde(rename = "type")] - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] highlight_type: Option<String>, } @@ -586,9 +585,9 @@ pub enum SimpleFieldOrString { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct ApiCollapse{ +pub struct ApiCollapse { field: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] inner_hits: Option<InnerHitsOneOrMore>, } @@ -603,15 +602,15 @@ pub enum InnerHitsOneOrMore { #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct InnerHits { - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] from: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] sort: Option<Vec<SortElement>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] name: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] collapse: Option<Box<ApiCollapse>>, } @@ -619,77 +618,77 @@ pub struct InnerHits { #[serde(deny_unknown_fields)] pub struct ApiAggregation { // bucket type aggregations - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] nested: Option<NestedAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] filter: Option<ApiQuery>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] histogram: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] terms: Option<TermsAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] significant_terms: Option<SimpleAggregation>, // metrics type aggregations - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] avg: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] min: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] max: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] sum: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] value_count: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] stats: Option<SimpleAggregation>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] percentiles: Option<SimpleAggregation>, // nested aggregations - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] aggs: Option<HashMap<String, Box<ApiAggregation>>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] aggregations: Option<HashMap<String, Box<ApiAggregation>>>, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct NestedAggregation{ +pub struct NestedAggregation { path: String, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct SimpleAggregation{ +pub struct SimpleAggregation { field: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] interval: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] missing: Option<StringOrNum>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] keyed: Option<bool>, } #[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] -pub struct DateHistogramAggregation{ +pub struct DateHistogramAggregation { field: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] fixed_interval: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] calendar_interval: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] format: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] time_zone: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] offset: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] order: Option<HashMap<String, String>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] keyed: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] missing: Option<StringOrNum>, } @@ -697,22 +696,22 @@ pub struct DateHistogramAggregation{ #[serde(deny_unknown_fields)] pub struct TermsAggregation { field: String, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] shard_size: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] min_doc_count: Option<u32>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] show_term_doc_count_error: Option<bool>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] order: Option<HashMap<String, String>>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] include: Option<StringOrArray>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] exclude: Option<StringOrArray>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] execution_hint: Option<String>, - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none")] missing: Option<StringOrNum>, } |