Last active
December 5, 2016 07:30
-
-
Save KodrAus/a242e49cc7f69114017c9d65733cbe4b to your computer and use it in GitHub Desktop.
elastic_requests codegen
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::borrow::Cow; | |
use std::ops::Deref; | |
// - Codegen once - | |
#[derive(Debug)] | |
pub struct Body<'a>(Cow<'a, [u8]>); | |
impl <'a> From<Vec<u8>> for Body<'a> { | |
fn from(value: Vec<u8>) -> Body<'a> { | |
Body(value.into()) | |
} | |
} | |
impl <'a> From<&'a [u8]> for Body<'a> { | |
fn from(value: &'a [u8]) -> Body<'a> { | |
Body(value.into()) | |
} | |
} | |
impl <'a> From<&'a str> for Body<'a> { | |
fn from(value: &'a str) -> Body<'a> { | |
Body(value.as_bytes().into()) | |
} | |
} | |
impl <'a> From<String> for Body<'a> { | |
fn from(value: String) -> Body<'a> { | |
Body(Cow::Owned(value.into())) | |
} | |
} | |
impl <'a> Deref for Body<'a> { | |
type Target = Cow<'a, [u8]>; | |
fn deref(&self) -> &Cow<'a, [u8]> { | |
&self.0 | |
} | |
} | |
#[derive(Debug)] | |
pub enum HttpMethod { | |
Head, | |
Get, | |
Post, | |
Put, | |
Delete, | |
} | |
macro_rules! wrapper { | |
($name:ident) => { | |
#[derive(Debug)] | |
pub struct $name<'a>(pub Cow<'a, str>); | |
impl <'a> From<&'a str> for $name<'a> { | |
fn from(value: &'a str) -> $name<'a> { | |
$name(Cow::Borrowed(value)) | |
} | |
} | |
impl <'a> From<String> for $name<'a> { | |
fn from(value: String) -> $name<'a> { | |
$name(Cow::Owned(value)) | |
} | |
} | |
impl <'a> ::std::ops::Deref for $name<'a> { | |
type Target = str; | |
fn deref(&self) -> &str { | |
&self.0 | |
} | |
} | |
} | |
} | |
wrapper!(Index); | |
wrapper!(Type); | |
#[derive(Debug)] | |
pub struct HttpRequest<'a> { | |
pub url: Cow<'a, str>, | |
pub method: HttpMethod, | |
pub body: Option<&'a Body<'a>>, | |
} | |
// - Codegen per endpoint - | |
pub enum ExistsAliasUrlParams<'a> { | |
None, | |
Index(Index<'a>), | |
IndexType(Index<'a>, Type<'a>), | |
} | |
pub struct ExistsAliasRequestParams<'a> { | |
pub url_params: ExistsAliasUrlParams<'a>, | |
pub body: Body<'a>, | |
} | |
impl<'a> ExistsAliasRequestParams<'a> { | |
pub fn new<IBody: Into<Body<'a>>>(body: IBody) -> ExistsAliasRequestParams<'a> { | |
ExistsAliasRequestParams { | |
url_params: ExistsAliasUrlParams::None, | |
body: body.into(), | |
} | |
} | |
pub fn index<IIndex: Into<Index<'a>>, IBody: Into<Body<'a>>> | |
(index: IIndex, | |
body: IBody) | |
-> ExistsAliasRequestParams<'a> { | |
ExistsAliasRequestParams { | |
url_params: ExistsAliasUrlParams::Index(index.into()), | |
body: body.into(), | |
} | |
} | |
pub fn index_ty<IIndex: Into<Index<'a>>, IType: Into<Type<'a>>, IBody: Into<Body<'a>>> | |
(index: IIndex, | |
ty: IType, | |
body: IBody) | |
-> ExistsAliasRequestParams<'a> { | |
ExistsAliasRequestParams { | |
url_params: ExistsAliasUrlParams::IndexType(index.into(), ty.into()), | |
body: body.into(), | |
} | |
} | |
} | |
impl<'a> ExistsAliasRequestParams<'a> { | |
pub fn url(&'a self) -> Cow<'a, str> { | |
match self.url_params { | |
ExistsAliasUrlParams::None => Cow::Borrowed("/_alias"), | |
ExistsAliasUrlParams::Index(ref index) => { | |
let mut url = String::with_capacity(8usize + index.len()); | |
url.push_str("/"); | |
url.push_str(index.as_ref()); | |
url.push_str("/_alias"); | |
Cow::Owned(url) | |
} | |
ExistsAliasUrlParams::IndexType(ref index, ref ty) => { | |
let mut url = String::with_capacity(9usize + index.len() + ty.len()); | |
url.push_str("/"); | |
url.push_str(index.as_ref()); | |
url.push_str("/_alias/"); | |
url.push_str(ty.as_ref()); | |
Cow::Owned(url) | |
} | |
} | |
} | |
} | |
impl<'a, 'b: 'a> Into<HttpRequest<'a>> for &'a ExistsAliasRequestParams<'b> { | |
fn into(self) -> HttpRequest<'a> { | |
HttpRequest { | |
url: self.url(), | |
method: HttpMethod::Post, | |
body: Some(&self.body), | |
} | |
} | |
} | |
const BODY: &'static [u8] = b"{}"; | |
fn main() { | |
// Request types are shells that borrow data: | |
// - The request body needs to outlive the endpoint request | |
// - The endpoint request needs to outlive the http request | |
// Below are examples showing a mix of owned and borrowed data | |
let req = ExistsAliasRequestParams::index_ty("index", String::from("ty"), BODY); | |
let req = ExistsAliasRequestParams::index_ty("index", "ty", Vec::new()); | |
fn do_req<'a, I: Into<HttpRequest<'a>>>(req: I) { | |
let http = req.into(); | |
println!("req: {:?}", http); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment