finchers_juniper/
graphiql.rs

1//! Endpoint for serving GraphiQL source.
2
3use finchers::endpoint::{ApplyContext, ApplyResult, Endpoint};
4use finchers::error::Error;
5
6use futures::{Future, Poll};
7
8use bytes::Bytes;
9use http::{header, Response};
10use juniper;
11
12/// Creates an endpoint which returns a generated GraphiQL interface.
13pub fn graphiql_source(endpoint_url: impl AsRef<str>) -> GraphiQLSource {
14    GraphiQLSource {
15        source: juniper::http::graphiql::graphiql_source(endpoint_url.as_ref()).into(),
16    }
17}
18
19#[allow(missing_docs)]
20#[derive(Debug)]
21pub struct GraphiQLSource {
22    source: Bytes,
23}
24
25impl GraphiQLSource {
26    /// Regenerate the GraphiQL interface with the specified endpoint URL.
27    pub fn regenerate(&mut self, endpoint_url: impl AsRef<str>) {
28        self.source = juniper::http::graphiql::graphiql_source(endpoint_url.as_ref()).into();
29    }
30}
31
32impl<'a> Endpoint<'a> for GraphiQLSource {
33    type Output = (Response<Bytes>,);
34    type Future = GraphiQLFuture<'a>;
35
36    fn apply(&'a self, _: &mut ApplyContext<'_>) -> ApplyResult<Self::Future> {
37        Ok(GraphiQLFuture(&self.source))
38    }
39}
40
41#[doc(hidden)]
42#[derive(Debug)]
43pub struct GraphiQLFuture<'a>(&'a Bytes);
44
45impl<'a> Future for GraphiQLFuture<'a> {
46    type Item = (Response<Bytes>,);
47    type Error = Error;
48
49    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
50        Ok((Response::builder()
51            .header(header::CONTENT_TYPE, "text/html; charset=utf-8")
52            .body(self.0.clone())
53            .expect("should be a valid response"),)
54            .into())
55    }
56}