use std::marker::PhantomData;
use futures::{Future, Poll};
use serde::de::DeserializeOwned;
use error::{Error, Result};
use client::{AsyncSender, Client, Sender, SyncSender};
use client::requests::RequestBuilder;
use client::requests::params::{Id, Index, Type};
use client::requests::endpoints::GetRequest;
use client::requests::raw::RawRequestInner;
use client::responses::GetResponse;
use types::document::DocumentType;
pub type GetRequestBuilder<TSender, TDocument> = RequestBuilder<TSender, GetRequestInner<TDocument>>;
#[doc(hidden)]
pub struct GetRequestInner<TDocument> {
index: Index<'static>,
ty: Type<'static>,
id: Id<'static>,
_marker: PhantomData<TDocument>,
}
impl<TSender> Client<TSender>
where
TSender: Sender,
{
pub fn document_get<TDocument>(&self, index: Index<'static>, id: Id<'static>) -> GetRequestBuilder<TSender, TDocument>
where
TDocument: DeserializeOwned + DocumentType,
{
let ty = TDocument::name().into();
RequestBuilder::new(
self.clone(),
None,
GetRequestInner {
index: index,
ty: ty,
id: id,
_marker: PhantomData,
},
)
}
}
impl<TDocument> GetRequestInner<TDocument> {
fn into_request(self) -> GetRequest<'static> {
GetRequest::for_index_ty_id(self.index, self.ty, self.id)
}
}
impl<TSender, TDocument> GetRequestBuilder<TSender, TDocument>
where
TSender: Sender,
{
pub fn ty<I>(mut self, ty: I) -> Self
where
I: Into<Type<'static>>,
{
self.inner.ty = ty.into();
self
}
}
impl<TDocument> GetRequestBuilder<SyncSender, TDocument>
where
TDocument: DeserializeOwned,
{
pub fn send(self) -> Result<GetResponse<TDocument>> {
let req = self.inner.into_request();
RequestBuilder::new(self.client, self.params, RawRequestInner::new(req))
.send()?
.into_response()
}
}
impl<TDocument> GetRequestBuilder<AsyncSender, TDocument>
where
TDocument: DeserializeOwned + Send + 'static,
{
pub fn send(self) -> Pending<TDocument> {
let req = self.inner.into_request();
let res_future = RequestBuilder::new(self.client, self.params, RawRequestInner::new(req))
.send()
.and_then(|res| res.into_response());
Pending::new(res_future)
}
}
pub struct Pending<TDocument> {
inner: Box<Future<Item = GetResponse<TDocument>, Error = Error>>,
}
impl<TDocument> Pending<TDocument> {
fn new<F>(fut: F) -> Self
where
F: Future<Item = GetResponse<TDocument>, Error = Error> + 'static,
{
Pending {
inner: Box::new(fut),
}
}
}
impl<TDocument> Future for Pending<TDocument>
where
TDocument: DeserializeOwned + Send + 'static,
{
type Item = GetResponse<TDocument>;
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.inner.poll()
}
}
#[cfg(test)]
mod tests {
use serde_json::Value;
use prelude::*;
#[test]
fn default_request() {
let client = SyncClientBuilder::new().build().unwrap();
let req = client
.document_get::<Value>(index("test-idx"), id("1"))
.inner
.into_request();
assert_eq!("/test-idx/value/1", req.url.as_ref());
}
#[test]
fn specify_ty() {
let client = SyncClientBuilder::new().build().unwrap();
let req = client
.document_get::<Value>(index("test-idx"), id("1"))
.ty("new-ty")
.inner
.into_request();
assert_eq!("/test-idx/new-ty/1", req.url.as_ref());
}
}