use serde::de::DeserializeOwned;
use serde::Deserialize;
use super::common::{OptionVal, Options};
use crate::{error::EsError, util::StrJoin, Client, EsResponse};
pub enum Preference {
Primary,
Local,
}
impl From<Preference> for OptionVal {
fn from(from: Preference) -> OptionVal {
OptionVal(
match from {
Preference::Primary => "_primary",
Preference::Local => "_local",
}
.to_owned(),
)
}
}
#[derive(Debug)]
pub struct GetOperation<'a, 'b> {
client: &'a mut Client,
index: &'b str,
doc_type: Option<&'b str>,
id: &'b str,
options: Options<'b>,
}
impl<'a, 'b> GetOperation<'a, 'b> {
pub fn new(client: &'a mut Client, index: &'b str, id: &'b str) -> Self {
GetOperation {
client,
index,
doc_type: None,
id,
options: Options::default(),
}
}
pub fn with_all_types(&'b mut self) -> &'b mut Self {
self.doc_type = Some("_all");
self
}
pub fn with_doc_type(&'b mut self, doc_type: &'b str) -> &'b mut Self {
self.doc_type = Some(doc_type);
self
}
pub fn with_fields(&'b mut self, fields: &[&'b str]) -> &'b mut Self {
self.options.push("fields", fields.iter().join(","));
self
}
add_option!(with_realtime, "realtime");
add_option!(with_source, "_source");
add_option!(with_routing, "routing");
add_option!(with_preference, "preference");
add_option!(with_refresh, "refresh");
add_option!(with_version, "version");
add_option!(with_version_type, "version_type");
pub fn send<T>(&'b mut self) -> Result<GetResult<T>, EsError>
where
T: DeserializeOwned,
{
let url = format!(
"/{}/{}/{}{}",
self.index,
self.doc_type.expect("No doc_type specified"),
self.id,
self.options
);
let response = self.client.get_op(&url)?;
Ok(response.read_response()?)
}
}
impl Client {
pub fn get<'a>(&'a mut self, index: &'a str, id: &'a str) -> GetOperation {
GetOperation::new(self, index, id)
}
}
#[derive(Debug, Deserialize)]
pub struct GetResult<T> {
#[serde(rename = "_index")]
pub index: String,
#[serde(rename = "_type")]
pub doc_type: String,
#[serde(rename = "_id")]
pub id: String,
#[serde(rename = "_version")]
pub version: Option<u64>,
pub found: bool,
#[serde(rename = "_source")]
pub source: Option<T>,
}
#[cfg(test)]
pub mod tests {
use crate::tests::{clean_db, make_client, TestDocument};
#[test]
fn test_get() {
let index_name = "test_get";
let mut client = make_client();
clean_db(&mut client, index_name);
{
let doc = TestDocument::new().with_int_field(3).with_bool_field(false);
client
.index(index_name, "test_type")
.with_id("TEST_GETTING")
.with_doc(&doc)
.send()
.unwrap();
}
{
let mut getter = client.get(index_name, "TEST_GETTING");
let result_wrapped = getter.with_doc_type("test_type").send();
let result = result_wrapped.unwrap();
assert_eq!(result.id, "TEST_GETTING");
let source: TestDocument = result.source.expect("Source document");
assert_eq!(source.str_field, "I am a test");
assert_eq!(source.int_field, 3);
assert_eq!(source.bool_field, false);
}
}
}