2020-06-03 06:50:06 +00:00
use crate ::utils ::{
get_rustdoc , parse_default , parse_default_with , parse_guards , parse_post_guards ,
parse_validator ,
} ;
2020-03-21 01:32:13 +00:00
use proc_macro2 ::TokenStream ;
use quote ::quote ;
2020-03-22 08:45:59 +00:00
use syn ::{ Attribute , AttributeArgs , Error , Lit , Meta , MetaList , NestedMeta , Result , Type } ;
pub struct CacheControl {
pub public : bool ,
pub max_age : usize ,
}
impl Default for CacheControl {
fn default ( ) -> Self {
Self {
public : true ,
max_age : 0 ,
}
}
}
impl CacheControl {
pub fn parse ( ls : & MetaList ) -> Result < Self > {
let mut cache_control = Self {
public : true ,
max_age : 0 ,
} ;
for meta in & ls . nested {
match meta {
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " max_age " ) {
if let Lit ::Int ( n ) = & nv . lit {
match n . base10_parse ::< usize > ( ) {
Ok ( n ) = > cache_control . max_age = n ,
Err ( err ) = > {
return Err ( Error ::new_spanned ( & nv . lit , err ) ) ;
}
}
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'max_age' must be integer. " ,
) ) ;
}
}
}
NestedMeta ::Meta ( Meta ::Path ( p ) ) = > {
if p . is_ident ( " public " ) {
cache_control . public = true ;
} else if p . is_ident ( " private " ) {
cache_control . public = false ;
}
}
_ = > { }
}
}
Ok ( cache_control )
}
}
2020-03-01 10:54:34 +00:00
pub struct Object {
2020-03-02 00:24:49 +00:00
pub internal : bool ,
2020-03-01 10:54:34 +00:00
pub name : Option < String > ,
pub desc : Option < String > ,
2020-03-22 08:45:59 +00:00
pub cache_control : CacheControl ,
2020-04-09 14:03:09 +00:00
pub extends : bool ,
2020-03-01 10:54:34 +00:00
}
impl Object {
pub fn parse ( args : AttributeArgs ) -> Result < Self > {
2020-03-02 00:24:49 +00:00
let mut internal = false ;
2020-03-01 10:54:34 +00:00
let mut name = None ;
let mut desc = None ;
2020-03-22 08:45:59 +00:00
let mut cache_control = CacheControl ::default ( ) ;
2020-04-09 14:03:09 +00:00
let mut extends = false ;
2020-03-01 10:54:34 +00:00
for arg in args {
match arg {
2020-03-02 00:24:49 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " internal " ) = > {
internal = true ;
}
2020-04-09 14:03:09 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " extends " ) = > {
extends = true ;
}
2020-03-01 10:54:34 +00:00
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
}
}
2020-03-22 08:45:59 +00:00
NestedMeta ::Meta ( Meta ::List ( ls ) ) = > {
if ls . path . is_ident ( " cache_control " ) {
cache_control = CacheControl ::parse ( & ls ) ? ;
}
}
2020-03-01 10:54:34 +00:00
_ = > { }
}
}
2020-03-02 00:24:49 +00:00
Ok ( Self {
internal ,
name ,
desc ,
2020-03-22 08:45:59 +00:00
cache_control ,
2020-04-09 14:03:09 +00:00
extends ,
2020-03-02 00:24:49 +00:00
} )
2020-03-01 10:54:34 +00:00
}
}
pub struct Argument {
2020-03-05 06:23:55 +00:00
pub name : Option < String > ,
2020-03-01 10:54:34 +00:00
pub desc : Option < String > ,
2020-05-26 10:34:43 +00:00
pub default : Option < TokenStream > ,
2020-03-22 01:34:32 +00:00
pub validator : TokenStream ,
2020-06-19 04:37:52 +00:00
pub key : bool , // for entity
2020-03-01 10:54:34 +00:00
}
2020-03-05 06:23:55 +00:00
impl Argument {
2020-03-21 07:07:11 +00:00
pub fn parse ( crate_name : & TokenStream , attrs : & [ Attribute ] ) -> Result < Self > {
2020-03-01 10:54:34 +00:00
let mut name = None ;
let mut desc = None ;
2020-03-05 06:23:55 +00:00
let mut default = None ;
2020-03-22 01:34:32 +00:00
let mut validator = quote! { None } ;
2020-06-19 04:37:52 +00:00
let mut key = false ;
2020-03-05 06:23:55 +00:00
for attr in attrs {
2020-03-22 01:34:32 +00:00
match attr . parse_meta ( ) ? {
Meta ::List ( ls ) if ls . path . is_ident ( " arg " ) = > {
2020-03-05 06:23:55 +00:00
for meta in & ls . nested {
2020-05-26 10:34:43 +00:00
if let NestedMeta ::Meta ( Meta ::Path ( p ) ) = meta {
if p . is_ident ( " default " ) {
default = Some ( quote! { Default ::default ( ) } ) ;
2020-06-19 04:37:52 +00:00
} else if p . is_ident ( " key " ) {
key = true ;
2020-05-26 10:34:43 +00:00
}
} else if let NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = meta {
2020-03-21 01:32:13 +00:00
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " default " ) {
2020-05-26 10:34:43 +00:00
default = Some ( parse_default ( & nv . lit ) ? ) ;
} else if nv . path . is_ident ( " default_with " ) {
default = Some ( parse_default_with ( & nv . lit ) ? ) ;
2020-03-05 06:23:55 +00:00
}
}
}
2020-03-21 01:32:13 +00:00
2020-03-22 01:34:32 +00:00
validator = parse_validator ( crate_name , & ls ) ? ;
2020-03-05 06:23:55 +00:00
}
_ = > { }
}
}
Ok ( Self {
name ,
desc ,
default ,
2020-03-22 01:34:32 +00:00
validator ,
2020-06-19 04:37:52 +00:00
key ,
2020-03-05 06:23:55 +00:00
} )
}
}
pub struct Field {
pub name : Option < String > ,
pub desc : Option < String > ,
pub deprecation : Option < String > ,
2020-03-22 08:45:59 +00:00
pub cache_control : CacheControl ,
2020-04-09 14:03:09 +00:00
pub external : bool ,
pub provides : Option < String > ,
pub requires : Option < String > ,
2020-06-23 06:42:57 +00:00
pub owned : bool ,
2020-05-01 23:57:34 +00:00
pub guard : Option < TokenStream > ,
2020-06-03 06:50:06 +00:00
pub post_guard : Option < TokenStream > ,
2020-03-05 06:23:55 +00:00
}
impl Field {
2020-05-01 23:57:34 +00:00
pub fn parse ( crate_name : & TokenStream , attrs : & [ Attribute ] ) -> Result < Option < Self > > {
2020-03-05 06:23:55 +00:00
let mut name = None ;
let mut desc = None ;
let mut deprecation = None ;
2020-03-22 08:45:59 +00:00
let mut cache_control = CacheControl ::default ( ) ;
2020-04-09 14:03:09 +00:00
let mut external = false ;
let mut provides = None ;
let mut requires = None ;
2020-06-23 06:42:57 +00:00
let mut owned = false ;
2020-05-01 23:57:34 +00:00
let mut guard = None ;
2020-06-03 06:50:06 +00:00
let mut post_guard = None ;
2020-03-05 06:23:55 +00:00
for attr in attrs {
2020-03-22 01:34:32 +00:00
match attr . parse_meta ( ) ? {
Meta ::List ( ls ) if ls . path . is_ident ( " field " ) = > {
2020-05-01 23:57:34 +00:00
guard = parse_guards ( crate_name , & ls ) ? ;
2020-06-03 06:50:06 +00:00
post_guard = parse_post_guards ( crate_name , & ls ) ? ;
2020-03-05 06:23:55 +00:00
for meta in & ls . nested {
2020-03-22 08:45:59 +00:00
match meta {
2020-04-27 04:57:52 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " skip " ) = > {
return Ok ( None ) ;
}
2020-04-09 14:03:09 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " external " ) = > {
external = true ;
}
2020-06-23 06:42:57 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " owned " ) = > {
owned = true ;
}
2020-04-21 07:40:19 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " ref " ) = > {
2020-06-23 06:42:57 +00:00
return Err ( Error ::new_spanned (
& p ,
" Attribute `ref` is no longer supported. By default, all fields resolver return borrowed value. If you want to return ownership value, use `owned` attribute. " ,
) ) ;
2020-04-21 07:40:19 +00:00
}
2020-03-22 08:45:59 +00:00
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " deprecation " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
deprecation = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'deprecation' should be a string. " ,
) ) ;
}
2020-04-09 14:03:09 +00:00
} else if nv . path . is_ident ( " provides " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
provides = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'provides' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " requires " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
requires = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'requires' should be a string. " ,
) ) ;
}
2020-03-21 01:32:13 +00:00
}
2020-03-22 08:45:59 +00:00
}
NestedMeta ::Meta ( Meta ::List ( ls ) ) = > {
if ls . path . is_ident ( " cache_control " ) {
cache_control = CacheControl ::parse ( ls ) ? ;
2020-03-01 10:54:34 +00:00
}
}
2020-03-22 08:45:59 +00:00
_ = > { }
2020-03-02 11:25:21 +00:00
}
2020-03-01 10:54:34 +00:00
}
}
2020-03-02 11:25:21 +00:00
_ = > { }
2020-03-01 10:54:34 +00:00
}
}
2020-05-10 04:41:05 +00:00
if desc . is_none ( ) {
desc = get_rustdoc ( attrs ) ? ;
}
2020-04-27 04:57:52 +00:00
Ok ( Some ( Self {
name ,
desc ,
deprecation ,
cache_control ,
external ,
provides ,
requires ,
2020-06-23 06:42:57 +00:00
owned ,
2020-05-01 23:57:34 +00:00
guard ,
2020-06-03 06:50:06 +00:00
post_guard ,
2020-04-27 04:57:52 +00:00
} ) )
2020-03-01 10:54:34 +00:00
}
}
pub struct Enum {
2020-03-02 00:24:49 +00:00
pub internal : bool ,
2020-03-01 10:54:34 +00:00
pub name : Option < String > ,
pub desc : Option < String > ,
}
impl Enum {
pub fn parse ( args : AttributeArgs ) -> Result < Self > {
2020-03-02 00:24:49 +00:00
let mut internal = false ;
2020-03-01 10:54:34 +00:00
let mut name = None ;
let mut desc = None ;
for arg in args {
match arg {
2020-03-02 00:24:49 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " internal " ) = > {
internal = true ;
}
2020-03-01 10:54:34 +00:00
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
}
}
_ = > { }
}
}
2020-03-02 00:24:49 +00:00
Ok ( Self {
internal ,
name ,
desc ,
} )
2020-03-01 10:54:34 +00:00
}
}
pub struct EnumItem {
pub name : Option < String > ,
pub desc : Option < String > ,
2020-03-03 03:48:00 +00:00
pub deprecation : Option < String > ,
2020-03-01 10:54:34 +00:00
}
impl EnumItem {
pub fn parse ( attrs : & [ Attribute ] ) -> Result < Self > {
let mut name = None ;
let mut desc = None ;
2020-03-03 03:48:00 +00:00
let mut deprecation = None ;
2020-03-01 10:54:34 +00:00
for attr in attrs {
if attr . path . is_ident ( " item " ) {
2020-03-22 01:34:32 +00:00
if let Meta ::List ( args ) = attr . parse_meta ( ) ? {
2020-03-01 10:54:34 +00:00
for meta in args . nested {
2020-03-21 01:32:13 +00:00
if let NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = meta {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " deprecation " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
deprecation = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'deprecation' should be a string. " ,
) ) ;
2020-03-01 10:54:34 +00:00
}
}
}
}
}
}
}
2020-05-10 04:41:05 +00:00
if desc . is_none ( ) {
desc = get_rustdoc ( attrs ) ? ;
}
2020-03-03 03:48:00 +00:00
Ok ( Self {
name ,
desc ,
deprecation ,
} )
2020-03-01 10:54:34 +00:00
}
}
pub struct InputField {
pub name : Option < String > ,
pub desc : Option < String > ,
2020-05-26 10:34:43 +00:00
pub default : Option < TokenStream > ,
2020-03-22 01:34:32 +00:00
pub validator : TokenStream ,
2020-09-03 12:00:33 +00:00
pub flatten : bool ,
2020-03-01 10:54:34 +00:00
}
impl InputField {
2020-03-21 07:07:11 +00:00
pub fn parse ( crate_name : & TokenStream , attrs : & [ Attribute ] ) -> Result < Self > {
2020-03-01 10:54:34 +00:00
let mut name = None ;
let mut desc = None ;
2020-03-03 03:48:00 +00:00
let mut default = None ;
2020-03-22 01:34:32 +00:00
let mut validator = quote! { None } ;
2020-09-03 12:00:33 +00:00
let mut flatten = false ;
2020-03-01 10:54:34 +00:00
for attr in attrs {
if attr . path . is_ident ( " field " ) {
2020-03-22 01:34:32 +00:00
if let Meta ::List ( args ) = & attr . parse_meta ( ) ? {
2020-03-21 01:32:13 +00:00
for meta in & args . nested {
2020-04-27 04:57:52 +00:00
match meta {
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " skip " ) = > {
return Err ( Error ::new_spanned (
meta ,
" Fields on InputObject are not allowed to be skipped " ,
) ) ;
}
2020-05-26 10:34:43 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " default " ) = > {
default = Some ( quote! { Default ::default ( ) } ) ;
}
2020-09-03 12:00:33 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " flatten " ) = > {
flatten = true ;
}
2020-04-27 04:57:52 +00:00
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " default " ) {
2020-05-26 10:34:43 +00:00
default = Some ( parse_default ( & nv . lit ) ? ) ;
} else if nv . path . is_ident ( " default_with " ) {
default = Some ( parse_default_with ( & nv . lit ) ? ) ;
2020-03-01 10:54:34 +00:00
}
}
2020-04-27 04:57:52 +00:00
_ = > { }
2020-03-01 10:54:34 +00:00
}
}
2020-03-21 01:32:13 +00:00
2020-03-22 01:34:32 +00:00
validator = parse_validator ( crate_name , & args ) ? ;
2020-03-01 10:54:34 +00:00
}
}
}
2020-05-10 04:41:05 +00:00
if desc . is_none ( ) {
desc = get_rustdoc ( attrs ) ? ;
}
2020-03-03 03:48:00 +00:00
Ok ( Self {
name ,
desc ,
default ,
2020-03-22 01:34:32 +00:00
validator ,
2020-09-03 12:00:33 +00:00
flatten ,
2020-03-03 03:48:00 +00:00
} )
}
}
pub struct InputObject {
pub internal : bool ,
pub name : Option < String > ,
pub desc : Option < String > ,
}
impl InputObject {
pub fn parse ( args : AttributeArgs ) -> Result < Self > {
let mut internal = false ;
let mut name = None ;
let mut desc = None ;
for arg in args {
match arg {
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " internal " ) = > {
internal = true ;
}
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
}
}
_ = > { }
}
}
2020-03-02 00:24:49 +00:00
Ok ( Self {
internal ,
name ,
desc ,
} )
2020-03-01 10:54:34 +00:00
}
}
2020-03-06 15:58:43 +00:00
pub struct InterfaceFieldArgument {
pub name : String ,
pub desc : Option < String > ,
pub ty : Type ,
2020-05-26 10:34:43 +00:00
pub default : Option < TokenStream > ,
2020-03-06 15:58:43 +00:00
}
impl InterfaceFieldArgument {
pub fn parse ( ls : & MetaList ) -> Result < Self > {
let mut name = None ;
let mut desc = None ;
let mut ty = None ;
let mut default = None ;
for meta in & ls . nested {
2020-05-26 10:34:43 +00:00
if let NestedMeta ::Meta ( Meta ::Path ( p ) ) = meta {
if p . is_ident ( " default " ) {
default = Some ( quote! { Default ::default ( ) } ) ;
}
} else if let NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = meta {
2020-03-21 01:32:13 +00:00
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " type " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
if let Ok ( ty2 ) = syn ::parse_str ::< syn ::Type > ( & lit . value ( ) ) {
ty = Some ( ty2 ) ;
2020-03-06 15:58:43 +00:00
} else {
2020-03-21 01:32:13 +00:00
return Err ( Error ::new_spanned ( & lit , " Expect type " ) ) ;
2020-03-06 15:58:43 +00:00
}
2020-03-21 01:32:13 +00:00
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'type' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " default " ) {
2020-05-26 10:34:43 +00:00
default = Some ( parse_default ( & nv . lit ) ? ) ;
} else if nv . path . is_ident ( " default_with " ) {
default = Some ( parse_default_with ( & nv . lit ) ? ) ;
2020-03-06 15:58:43 +00:00
}
}
}
if name . is_none ( ) {
return Err ( Error ::new_spanned ( ls , " Missing name " ) ) ;
}
if ty . is_none ( ) {
return Err ( Error ::new_spanned ( ls , " Missing type " ) ) ;
}
Ok ( Self {
name : name . unwrap ( ) ,
desc ,
ty : ty . unwrap ( ) ,
default ,
} )
}
}
pub struct InterfaceField {
pub name : String ,
2020-05-27 02:25:23 +00:00
pub method : Option < String > ,
2020-03-06 15:58:43 +00:00
pub desc : Option < String > ,
pub ty : Type ,
pub args : Vec < InterfaceFieldArgument > ,
pub deprecation : Option < String > ,
2020-04-09 14:03:09 +00:00
pub external : bool ,
pub provides : Option < String > ,
pub requires : Option < String > ,
2020-03-06 15:58:43 +00:00
}
impl InterfaceField {
pub fn parse ( ls : & MetaList ) -> Result < Self > {
let mut name = None ;
2020-05-27 02:25:23 +00:00
let mut method = None ;
2020-03-06 15:58:43 +00:00
let mut desc = None ;
let mut ty = None ;
let mut args = Vec ::new ( ) ;
let mut deprecation = None ;
2020-04-09 14:03:09 +00:00
let mut external = false ;
let mut provides = None ;
let mut requires = None ;
2020-03-06 15:58:43 +00:00
for meta in & ls . nested {
match meta {
2020-04-09 14:03:09 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " external " ) = > {
external = true ;
}
2020-03-06 15:58:43 +00:00
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
2020-05-27 02:25:23 +00:00
} else if nv . path . is_ident ( " method " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
method = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'method' should be a string. " ,
) ) ;
}
2020-03-06 15:58:43 +00:00
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " type " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
if let Ok ( ty2 ) = syn ::parse_str ::< syn ::Type > ( & lit . value ( ) ) {
ty = Some ( ty2 ) ;
} else {
return Err ( Error ::new_spanned ( & lit , " Expect type " ) ) ;
}
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'type' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " deprecation " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
deprecation = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'deprecation' should be a string. " ,
) ) ;
}
2020-04-09 14:03:09 +00:00
} else if nv . path . is_ident ( " provides " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
provides = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'provides' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " requires " ) {
if let syn ::Lit ::Str ( lit ) = & nv . lit {
requires = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'requires' should be a string. " ,
) ) ;
}
2020-03-06 15:58:43 +00:00
}
}
NestedMeta ::Meta ( Meta ::List ( ls ) ) if ls . path . is_ident ( " arg " ) = > {
args . push ( InterfaceFieldArgument ::parse ( ls ) ? ) ;
}
_ = > { }
}
}
if name . is_none ( ) {
return Err ( Error ::new_spanned ( ls , " Missing name " ) ) ;
}
if ty . is_none ( ) {
return Err ( Error ::new_spanned ( ls , " Missing type " ) ) ;
}
Ok ( Self {
name : name . unwrap ( ) ,
2020-05-27 02:25:23 +00:00
method ,
2020-03-06 15:58:43 +00:00
desc ,
ty : ty . unwrap ( ) ,
args ,
deprecation ,
2020-04-09 14:03:09 +00:00
external ,
requires ,
provides ,
2020-03-06 15:58:43 +00:00
} )
}
}
pub struct Interface {
pub internal : bool ,
pub name : Option < String > ,
pub desc : Option < String > ,
pub fields : Vec < InterfaceField > ,
2020-04-09 14:03:09 +00:00
pub extends : bool ,
2020-03-06 15:58:43 +00:00
}
impl Interface {
pub fn parse ( args : AttributeArgs ) -> Result < Self > {
let mut internal = false ;
let mut name = None ;
let mut desc = None ;
let mut fields = Vec ::new ( ) ;
2020-04-09 14:03:09 +00:00
let mut extends = false ;
2020-03-06 15:58:43 +00:00
for arg in args {
match arg {
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " internal " ) = > {
internal = true ;
}
2020-04-09 14:03:09 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) if p . is_ident ( " extends " ) = > {
extends = true ;
2020-03-06 15:58:43 +00:00
}
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
}
}
NestedMeta ::Meta ( Meta ::List ( ls ) ) if ls . path . is_ident ( " field " ) = > {
fields . push ( InterfaceField ::parse ( & ls ) ? ) ;
}
_ = > { }
}
}
Ok ( Self {
internal ,
name ,
desc ,
fields ,
2020-04-09 14:03:09 +00:00
extends ,
2020-03-06 15:58:43 +00:00
} )
}
}
2020-04-17 03:06:33 +00:00
2020-04-27 09:58:10 +00:00
pub struct Scalar {
pub internal : bool ,
2020-05-19 05:27:01 +00:00
pub name : Option < String > ,
pub desc : Option < String > ,
2020-04-27 09:58:10 +00:00
}
impl Scalar {
pub fn parse ( args : AttributeArgs ) -> Result < Self > {
let mut internal = false ;
2020-05-19 05:27:01 +00:00
let mut name = None ;
let mut desc = None ;
2020-04-27 09:58:10 +00:00
for arg in args {
match arg {
2020-05-19 05:27:01 +00:00
NestedMeta ::Meta ( Meta ::Path ( p ) ) = > {
if p . is_ident ( " internal " ) {
internal = true ;
}
}
NestedMeta ::Meta ( Meta ::NameValue ( nv ) ) = > {
if nv . path . is_ident ( " name " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
name = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'name' should be a string. " ,
) ) ;
}
} else if nv . path . is_ident ( " desc " ) {
if let syn ::Lit ::Str ( lit ) = nv . lit {
desc = Some ( lit . value ( ) ) ;
} else {
return Err ( Error ::new_spanned (
& nv . lit ,
" Attribute 'desc' should be a string. " ,
) ) ;
}
}
2020-04-27 09:58:10 +00:00
}
_ = > { }
}
}
2020-05-19 05:27:01 +00:00
Ok ( Self {
internal ,
name ,
desc ,
} )
2020-04-27 09:58:10 +00:00
}
}
2020-05-01 23:57:34 +00:00
2020-06-03 06:50:06 +00:00
pub struct Entity { }
2020-05-01 23:57:34 +00:00
impl Entity {
2020-06-03 06:50:06 +00:00
pub fn parse ( _crate_name : & TokenStream , attrs : & [ Attribute ] ) -> Result < Option < Self > > {
2020-05-01 23:57:34 +00:00
for attr in attrs {
match attr . parse_meta ( ) ? {
Meta ::List ( ls ) if ls . path . is_ident ( " entity " ) = > {
2020-06-03 06:50:06 +00:00
return Ok ( Some ( Self { } ) ) ;
2020-05-01 23:57:34 +00:00
}
Meta ::Path ( p ) if p . is_ident ( " entity " ) = > {
2020-06-03 06:50:06 +00:00
return Ok ( Some ( Self { } ) ) ;
2020-05-01 23:57:34 +00:00
}
_ = > { }
}
}
Ok ( None )
}
}