ExprStruct --> Request
This commit is contained in:
parent
ba6eef9c76
commit
a1929e38cf
@ -1,23 +1,13 @@
|
|||||||
use quote::{ToTokens, Tokens};
|
use quote::{ToTokens, Tokens};
|
||||||
use syn::synom::Synom;
|
use syn::synom::Synom;
|
||||||
use syn::{Field, FieldsNamed, Meta, NestedMeta};
|
use syn::{ExprStruct, Field, FieldValue, FieldsNamed, Meta, NestedMeta};
|
||||||
|
|
||||||
use api::strip_serde_attrs;
|
use api::strip_serde_attrs;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
fields: Vec<RequestField>,
|
fields: Vec<RequestField>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Synom for Request {
|
|
||||||
named!(parse -> Self, do_parse!(
|
|
||||||
fields: syn!(FieldsNamed) >>
|
|
||||||
(Request {
|
|
||||||
fields,
|
|
||||||
})
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Request {
|
impl Request {
|
||||||
pub fn has_body_fields(&self) -> bool {
|
pub fn has_body_fields(&self) -> bool {
|
||||||
self.fields.iter().any(|field| field.is_body())
|
self.fields.iter().any(|field| field.is_body())
|
||||||
@ -35,7 +25,7 @@ impl Request {
|
|||||||
self.fields.iter().filter(|field| field.is_path()).count()
|
self.fields.iter().filter(|field| field.is_path()).count()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newtype_body_field(&self) -> Option<&Field> {
|
pub fn newtype_body_field(&self) -> Option<&FieldValue> {
|
||||||
for request_field in self.fields.iter() {
|
for request_field in self.fields.iter() {
|
||||||
match *request_field {
|
match *request_field {
|
||||||
RequestField::NewtypeBody(ref field) => {
|
RequestField::NewtypeBody(ref field) => {
|
||||||
@ -75,41 +65,39 @@ impl Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Field>> for Request {
|
impl From<ExprStruct> for Request {
|
||||||
fn from(fields: Vec<Field>) -> Self {
|
fn from(expr: ExprStruct) -> Self {
|
||||||
let mut has_newtype_body = false;
|
let mut has_newtype_body = false;
|
||||||
|
|
||||||
let request_fields = fields.into_iter().map(|mut field| {
|
let fields = expr.fields.into_iter().map(|mut field_value| {
|
||||||
let mut request_field_kind = RequestFieldKind::Body;
|
let mut field_kind = RequestFieldKind::Body;
|
||||||
|
|
||||||
field.attrs = field.attrs.into_iter().filter(|attr| {
|
field_value.attrs = field_value.attrs.into_iter().filter(|attr| {
|
||||||
let (attr_ident, nested_meta_items) = match attr.value {
|
let meta = attr.interpret_meta()
|
||||||
Meta::List(ref attr_ident, ref nested_meta_items) => (attr_ident, nested_meta_items),
|
.expect("ruma_api! could not parse request field attributes");
|
||||||
_ => return true,
|
|
||||||
};
|
|
||||||
|
|
||||||
if attr_ident != "ruma_api" {
|
let Meta::List(meta_list) = meta;
|
||||||
|
|
||||||
|
if meta_list.ident.as_ref() != "ruma_api" {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for nested_meta_item in nested_meta_items {
|
for nested_meta_item in meta_list.nested {
|
||||||
match *nested_meta_item {
|
match nested_meta_item {
|
||||||
NestedMeta::Meta(ref meta_item) => {
|
NestedMeta::Meta(meta_item) => {
|
||||||
match *meta_item {
|
match meta_item {
|
||||||
Meta::Word(ref ident) => {
|
Meta::Word(ident) => {
|
||||||
if ident == "body" {
|
match ident.as_ref() {
|
||||||
|
"body" => {
|
||||||
has_newtype_body = true;
|
has_newtype_body = true;
|
||||||
request_field_kind = RequestFieldKind::NewtypeBody;
|
field_kind = RequestFieldKind::NewtypeBody;
|
||||||
} else if ident == "header" {
|
}
|
||||||
request_field_kind = RequestFieldKind::Header;
|
"header" => field_kind = RequestFieldKind::Header,
|
||||||
} else if ident == "path" {
|
"path" => field_kind = RequestFieldKind::Path,
|
||||||
request_field_kind = RequestFieldKind::Path;
|
"query" => field_kind = RequestFieldKind::Query,
|
||||||
} else if ident == "query" {
|
_ => panic!(
|
||||||
request_field_kind = RequestFieldKind::Query;
|
|
||||||
} else {
|
|
||||||
panic!(
|
|
||||||
"ruma_api! attribute meta item on requests must be: body, header, path, or query"
|
"ruma_api! attribute meta item on requests must be: body, header, path, or query"
|
||||||
);
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
@ -126,18 +114,18 @@ impl From<Vec<Field>> for Request {
|
|||||||
false
|
false
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
if request_field_kind == RequestFieldKind::Body {
|
if field_kind == RequestFieldKind::Body {
|
||||||
assert!(
|
assert!(
|
||||||
!has_newtype_body,
|
!has_newtype_body,
|
||||||
"ruma_api! requests cannot have both normal body fields and a newtype body field"
|
"ruma_api! requests cannot have both normal body fields and a newtype body field"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestField::new(request_field_kind, field)
|
RequestField::new(field_kind, field_value)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
Request {
|
Request {
|
||||||
fields: request_fields,
|
fields,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,17 +239,16 @@ impl ToTokens for Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum RequestField {
|
pub enum RequestField {
|
||||||
Body(Field),
|
Body(FieldValue),
|
||||||
Header(Field),
|
Header(FieldValue),
|
||||||
NewtypeBody(Field),
|
NewtypeBody(FieldValue),
|
||||||
Path(Field),
|
Path(FieldValue),
|
||||||
Query(Field),
|
Query(FieldValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RequestField {
|
impl RequestField {
|
||||||
fn new(kind: RequestFieldKind, field: Field) -> RequestField {
|
fn new(kind: RequestFieldKind, field: FieldValue) -> RequestField {
|
||||||
match kind {
|
match kind {
|
||||||
RequestFieldKind::Body => RequestField::Body(field),
|
RequestFieldKind::Body => RequestField::Body(field),
|
||||||
RequestFieldKind::Header => RequestField::Header(field),
|
RequestFieldKind::Header => RequestField::Header(field),
|
||||||
@ -293,7 +280,7 @@ impl RequestField {
|
|||||||
self.kind() == RequestFieldKind::Query
|
self.kind() == RequestFieldKind::Query
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field(&self) -> &Field {
|
fn field(&self) -> &FieldValue {
|
||||||
match *self {
|
match *self {
|
||||||
RequestField::Body(ref field) => field,
|
RequestField::Body(ref field) => field,
|
||||||
RequestField::Header(ref field) => field,
|
RequestField::Header(ref field) => field,
|
||||||
@ -303,7 +290,7 @@ impl RequestField {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_(&self, kind: RequestFieldKind) -> Option<&Field> {
|
fn field_(&self, kind: RequestFieldKind) -> Option<&FieldValue> {
|
||||||
if self.kind() == kind {
|
if self.kind() == kind {
|
||||||
Some(self.field())
|
Some(self.field())
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user