use serde::ser::Serialize;
use serde::Deserialize;
use crate::{error::EsError, Client, EsResponse};
use super::common::{OptionVal, Options};
pub enum OpType {
Create,
}
impl From<OpType> for OptionVal {
fn from(from: OpType) -> OptionVal {
match from {
OpType::Create => OptionVal("create".to_owned()),
}
}
}
#[derive(Debug)]
pub struct IndexOperation<'a, 'b, E: Serialize + 'b> {
client: &'a mut Client,
index: &'b str,
doc_type: &'b str,
id: Option<&'b str>,
options: Options<'b>,
document: Option<&'b E>,
}
impl<'a, 'b, E: Serialize + 'b> IndexOperation<'a, 'b, E> {
pub fn new(
client: &'a mut Client,
index: &'b str,
doc_type: &'b str,
) -> IndexOperation<'a, 'b, E> {
IndexOperation {
client,
index,
doc_type,
id: None,
options: Options::default(),
document: None,
}
}
pub fn with_doc(&'b mut self, doc: &'b E) -> &'b mut Self {
self.document = Some(doc);
self
}
pub fn with_id(&'b mut self, id: &'b str) -> &'b mut Self {
self.id = Some(id);
self
}
add_option!(with_ttl, "ttl");
add_option!(with_version, "version");
add_option!(with_version_type, "version_type");
add_option!(with_op_type, "op_type");
add_option!(with_routing, "routing");
add_option!(with_parent, "parent");
add_option!(with_timestamp, "timestamp");
add_option!(with_refresh, "refresh");
add_option!(with_timeout, "timeout");
pub fn send(&'b mut self) -> Result<IndexResult, EsError> {
let response = (match self.id {
Some(ref id) => {
let url = format!("/{}/{}/{}{}", self.index, self.doc_type, id, self.options);
match self.document {
Some(ref doc) => self.client.put_body_op(&url, doc),
None => self.client.put_op(&url),
}
}
None => {
let url = format!("/{}/{}{}", self.index, self.doc_type, self.options);
match self.document {
Some(ref doc) => self.client.post_body_op(&url, doc),
None => self.client.post_op(&url),
}
}
})?;
Ok(response.read_response()?)
}
}
impl Client {
pub fn index<'a, 'b, E: Serialize>(
&'a mut self,
index: &'b str,
doc_type: &'b str,
) -> IndexOperation<'a, 'b, E> {
IndexOperation::new(self, index, doc_type)
}
}
#[derive(Debug, Deserialize)]
pub struct IndexResult {
#[serde(rename = "_index")]
pub index: String,
#[serde(rename = "_type")]
pub doc_type: String,
#[serde(rename = "_id")]
pub id: String,
#[serde(rename = "_version")]
pub version: u64,
pub created: bool,
}
#[cfg(test)]
pub mod tests {
use crate::tests::{clean_db, make_client, TestDocument};
use crate::units::Duration;
use super::OpType;
#[test]
fn test_indexing() {
let index_name = "test_indexing";
let mut client = make_client();
clean_db(&mut client, index_name);
{
let result_wrapped = client
.index(index_name, "test_type")
.with_doc(&TestDocument::new().with_int_field(1))
.with_ttl(&Duration::milliseconds(927_500))
.send();
println!("TEST RESULT: {:?}", result_wrapped);
let result = result_wrapped.unwrap();
assert_eq!(result.created, true);
assert_eq!(result.index, index_name);
assert_eq!(result.doc_type, "test_type");
assert!(!result.id.is_empty());
assert_eq!(result.version, 1);
}
{
let result_wrapped = client
.index(index_name, "test_type")
.with_doc(&TestDocument::new().with_int_field(2))
.with_id("TEST_INDEXING_2")
.with_op_type(OpType::Create)
.send();
let result = result_wrapped.unwrap();
assert_eq!(result.created, true);
assert_eq!(result.index, index_name);
assert_eq!(result.doc_type, "test_type");
assert_eq!(result.id, "TEST_INDEXING_2");
assert!(result.version >= 1);
}
}
}