Skip to content

Commit

Permalink
Merge pull request #37 from KodrAus/feat/index-response
Browse files Browse the repository at this point in the history
Refactor Parsing
  • Loading branch information
KodrAus authored May 22, 2017
2 parents d456b8b + 6631b13 commit f2ee7c4
Show file tree
Hide file tree
Showing 24 changed files with 611 additions and 421 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Stephan Buys <stephan.buys@panoptix.co.za>"]
name = "elastic_responses"
version = "0.7.2"
version = "0.8.0"
license = "MIT/Apache-2.0"
description = "Parses search results from Elasticsearch and presents results using convenient iterators."
documentation = "https://docs.rs/elastic_responses"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Query your Elasticsearch Cluster, then iterate through the results:
let mut res = client.elastic_req(&params, SearchRequest::for_index("_all", body)).unwrap();

// Parse body to JSON
let body_as_json: SearchResponse = res.json().unwrap();
let body_as_json = parse::<SearchResponse>().from_reader(res.status().to_u16(), res).unwrap();

// Use hits() or aggs() iterators
// Hits
Expand All @@ -55,7 +55,7 @@ Bulk response operations are split by whether they succeeded or failed:
let mut res = client.elastic_req(&params, BulkRequest::new(body)).unwrap();

// Parse body to JSON
let body_as_json: BulkResponse = res.json().unwrap();
let body_as_json = parse::<BulkResponse>().from_reader(res.status().to_u16(), res).unwrap();

// Do something with successful operations
for op in body_as_json.items.ok {
Expand Down
9 changes: 3 additions & 6 deletions samples/bulk/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern crate elastic_responses;

use elastic_reqwest::ElasticClient;
use elastic_reqwest::req::BulkRequest;
use elastic_responses::{HttpResponse, BulkErrorsResponse};
use elastic_responses::{parse, BulkErrorsResponse};

fn get_req() -> String {
let mut bulk = String::new();
Expand All @@ -31,13 +31,10 @@ fn main() {
let (client, params) = elastic_reqwest::default().unwrap();

// Send the request and read the response.
let http_res = {
let res = client.elastic_req(&params, BulkRequest::new(get_req())).unwrap();
HttpResponse::from_read(res.status().to_u16(), res)
};
let res = client.elastic_req(&params, BulkRequest::new(get_req())).unwrap();

//Parse body to JSON. You could also use `BulkErrorsResponse`.
let body_as_json: BulkErrorsResponse = http_res.into_response().unwrap();
let body_as_json: BulkErrorsResponse = parse::<BulkErrorsResponse>().from_reader(res.status().to_u16(), res).unwrap();

println!("{:?}", body_as_json);
}
9 changes: 3 additions & 6 deletions samples/search/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extern crate elastic_responses;

use elastic_reqwest::{ElasticClient};
use elastic_reqwest::req::SearchRequest;
use elastic_responses::{HttpResponse, SearchResponse};
use elastic_responses::{parse, SearchResponse};

fn main() {

Expand Down Expand Up @@ -67,13 +67,10 @@ fn main() {
});

// Send the request and read the response.
let http_res = {
let res = client.elastic_req(&params, SearchRequest::for_index("_all", body)).unwrap();
HttpResponse::from_read(res.status().to_u16(), res)
};
let res = client.elastic_req(&params, SearchRequest::for_index("_all", body)).unwrap();

//Parse body to JSON
let body_as_json: SearchResponse = http_res.into_response().unwrap();
let body_as_json: SearchResponse = parse::<SearchResponse>().from_reader(res.status().to_u16(), res).unwrap();

//Use hits() or aggs() iterators
//Hits
Expand Down
13 changes: 7 additions & 6 deletions src/bulk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use serde::de::{Deserialize, Deserializer, Visitor, Error as DeError, SeqAccess,
use serde_json::Value;
use common::Shards;

use super::HttpResponseHead;
use parse::{IsOk, ResponseBody, Unbuffered, MaybeOkResponse};
use parsing::{IsOk, HttpResponseHead, ResponseBody, Unbuffered, MaybeOkResponse};
use error::*;

use std::cmp;
Expand All @@ -13,6 +12,8 @@ use std::error::Error;

type BulkError = Value;

type DefaultAllocatedField = String;

/// Response for a [bulk request](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html).
///
/// This type splits successful and failed bulk operations so it's easier
Expand Down Expand Up @@ -90,7 +91,7 @@ type BulkError = Value;
/// # }
/// ```
#[derive(Deserialize, Debug, Clone)]
pub struct BulkResponse<TIndex = String, TType = String, TId = String> {
pub struct BulkResponse<TIndex = DefaultAllocatedField, TType = DefaultAllocatedField, TId = DefaultAllocatedField> {
pub took: u64,
errors: bool,
pub items: BulkItems<TIndex, TType, TId>,
Expand Down Expand Up @@ -170,7 +171,7 @@ impl<TIndex, TType, TId> BulkResponse<TIndex, TType, TId> {
/// ```
#[derive(Deserialize, Debug, Clone)]
#[serde(bound(deserialize = "TIndex: Deserialize<'de>, TType: Deserialize<'de>, TId: Deserialize<'de>"))]
pub struct BulkErrorsResponse<TIndex = String, TType = String, TId = String> {
pub struct BulkErrorsResponse<TIndex = DefaultAllocatedField, TType = DefaultAllocatedField, TId = DefaultAllocatedField> {
pub took: u64,
errors: bool,
#[serde(deserialize_with = "deserialize_bulk_item_errors")]
Expand All @@ -189,7 +190,7 @@ impl<TIndex, TType, TId> BulkErrorsResponse<TIndex, TType, TId> {

/// A successful bulk response item.
#[derive(Debug, Clone)]
pub struct BulkItem<TIndex, TType, TId> {
pub struct BulkItem<TIndex = DefaultAllocatedField, TType = DefaultAllocatedField, TId = DefaultAllocatedField> {
pub action: BulkAction,
pub index: TIndex,
pub ty: TType,
Expand All @@ -202,7 +203,7 @@ pub struct BulkItem<TIndex, TType, TId> {

/// A failed bulk response item.
#[derive(Debug, Clone)]
pub struct BulkItemError<TIndex, TType, TId> {
pub struct BulkItemError<TIndex = DefaultAllocatedField, TType = DefaultAllocatedField, TId = DefaultAllocatedField> {
pub action: BulkAction,
pub index: TIndex,
pub ty: TType,
Expand Down
17 changes: 17 additions & 0 deletions src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use parsing::{IsOk, HttpResponseHead, ResponseBody, Unbuffered, MaybeOkResponse};
use error::*;

/// A standard command acknowledgement response.
#[derive(Deserialize, Debug, Clone)]
pub struct CommandResponse {
pub acknowledged: bool
}

impl IsOk for CommandResponse {
fn is_ok<B: ResponseBody>(head: HttpResponseHead, body: Unbuffered<B>) -> Result<MaybeOkResponse<B>, ParseResponseError> {
match head.status() {
200...299 => Ok(MaybeOkResponse::ok(body)),
_ => Ok(MaybeOkResponse::err(body)),
}
}
}
11 changes: 11 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ quick_error! {
description("request parse error")
display("request parse error: '{}' on line: {}, col: {}", reason, line, col)
}
MapperParsing { reason: String } {
description("mapper parse error")
display("mapper parse error: '{}'", reason)
}
ActionRequestValidation { reason: String }
Other(v: Map<String, Value>) {
description("error response from Elasticsearch")
Expand Down Expand Up @@ -111,6 +115,13 @@ impl From<Map<String, Value>> for ApiError {
reason: reason.into(),
}
}
"mapper_parsing_exception" => {
let reason = error_key!(obj[reason]: |v| v.as_str());

ApiError::MapperParsing {
reason: reason.into(),
}
}
"action_request_validation_exception" => {
let reason = error_key!(obj[reason]: |v| v.as_str());

Expand Down
5 changes: 3 additions & 2 deletions src/get.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use serde::de::DeserializeOwned;
use serde_json::Value;

use super::HttpResponseHead;
use parse::{IsOk, ResponseBody, Unbuffered, MaybeOkResponse};
use parsing::{IsOk, HttpResponseHead, ResponseBody, Unbuffered, MaybeOkResponse};
use error::*;

/// Response for a [get document request](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html).
Expand All @@ -12,6 +11,8 @@ pub struct GetResponseOf<T> {
pub index: String,
#[serde(rename = "_type")]
pub ty: String,
#[serde(rename = "_id")]
pub id: String,
#[serde(rename = "_version")]
pub version: Option<u32>,
pub found: bool,
Expand Down
28 changes: 28 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use common::Shards;
use parsing::{IsOk, HttpResponseHead, ResponseBody, Unbuffered, MaybeOkResponse};
use error::*;

/// Response for an [index document request](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html).
#[derive(Deserialize, Debug)]
pub struct IndexResponse {
#[serde(rename = "_index")]
pub index: String,
#[serde(rename = "_type")]
pub ty: String,
#[serde(rename = "_id")]
pub id: String,
#[serde(rename = "_version")]
pub version: Option<u32>,
pub created: bool,
#[serde(rename = "_shards")]
pub shards: Shards,
}

impl IsOk for IndexResponse {
fn is_ok<B: ResponseBody>(head: HttpResponseHead, body: Unbuffered<B>) -> Result<MaybeOkResponse<B>, ParseResponseError> {
match head.status() {
200...299 => Ok(MaybeOkResponse::ok(body)),
_ => Ok(MaybeOkResponse::err(body)),
}
}
}
Loading

0 comments on commit f2ee7c4

Please sign in to comment.