mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
extract event_err ty info from Flowy_Event macro
This commit is contained in:
parent
6f3a03fa07
commit
e998c9a532
@ -29,7 +29,7 @@ impl<'a> ASTContainer<'a> {
|
|||||||
},
|
},
|
||||||
syn::Data::Enum(data) => {
|
syn::Data::Enum(data) => {
|
||||||
// https://docs.rs/syn/1.0.48/syn/struct.DataEnum.html
|
// https://docs.rs/syn/1.0.48/syn/struct.DataEnum.html
|
||||||
ASTData::Enum(enum_from_ast(cx, &data.variants))
|
ASTData::Enum(enum_from_ast(cx, &data.variants, &ast.attrs))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,11 +209,12 @@ pub fn struct_from_ast<'a>(cx: &Ctxt, fields: &'a syn::Fields) -> (ASTStyle, Vec
|
|||||||
pub fn enum_from_ast<'a>(
|
pub fn enum_from_ast<'a>(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
variants: &'a Punctuated<syn::Variant, Token![,]>,
|
variants: &'a Punctuated<syn::Variant, Token![,]>,
|
||||||
|
enum_attrs: &Vec<syn::Attribute>,
|
||||||
) -> Vec<ASTEnumVariant<'a>> {
|
) -> Vec<ASTEnumVariant<'a>> {
|
||||||
variants
|
variants
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|variant| {
|
.flat_map(|variant| {
|
||||||
let attrs = attr::ASTEnumAttrVariant::from_ast(cx, variant);
|
let attrs = attr::ASTEnumAttrVariant::from_ast(cx, variant, enum_attrs);
|
||||||
|
|
||||||
let (style, fields) = struct_from_ast(cx, &variant.fields);
|
let (style, fields) = struct_from_ast(cx, &variant.fields);
|
||||||
Some(ASTEnumVariant {
|
Some(ASTEnumVariant {
|
||||||
|
@ -5,6 +5,7 @@ use syn::{
|
|||||||
self,
|
self,
|
||||||
parse::{self, Parse},
|
parse::{self, Parse},
|
||||||
Meta::{List, NameValue, Path},
|
Meta::{List, NameValue, Path},
|
||||||
|
NestedMeta,
|
||||||
NestedMeta::{Lit, Meta},
|
NestedMeta::{Lit, Meta},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,6 +261,7 @@ pub enum Default {
|
|||||||
pub struct EventAttrs {
|
pub struct EventAttrs {
|
||||||
input: Option<syn::Path>,
|
input: Option<syn::Path>,
|
||||||
output: Option<syn::Path>,
|
output: Option<syn::Path>,
|
||||||
|
error_ty: Option<String>,
|
||||||
pub ignore: bool,
|
pub ignore: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +273,7 @@ pub struct ASTEnumAttrVariant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ASTEnumAttrVariant {
|
impl ASTEnumAttrVariant {
|
||||||
pub fn from_ast(ctxt: &Ctxt, variant: &syn::Variant) -> Self {
|
pub fn from_ast(ctxt: &Ctxt, variant: &syn::Variant, enum_attrs: &Vec<syn::Attribute>) -> Self {
|
||||||
let name = variant.ident.to_string();
|
let name = variant.ident.to_string();
|
||||||
let mut value = String::new();
|
let mut value = String::new();
|
||||||
if variant.discriminant.is_some() {
|
if variant.discriminant.is_some() {
|
||||||
@ -287,60 +289,7 @@ impl ASTEnumAttrVariant {
|
|||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut event_attrs = EventAttrs {
|
let event_attrs = get_event_attrs_from(ctxt, &variant.attrs, enum_attrs);
|
||||||
input: None,
|
|
||||||
output: None,
|
|
||||||
ignore: false,
|
|
||||||
};
|
|
||||||
variant.attrs.iter().for_each(|attr| match get_meta_items(ctxt, attr) {
|
|
||||||
Ok(meta_items) => {
|
|
||||||
for meta_item in meta_items {
|
|
||||||
match &meta_item {
|
|
||||||
Meta(NameValue(name_value)) => {
|
|
||||||
if name_value.path == EVENT_INPUT {
|
|
||||||
if let syn::Lit::Str(s) = &name_value.lit {
|
|
||||||
let input_type = parse_lit_str(s)
|
|
||||||
.map_err(|_| {
|
|
||||||
ctxt.error_spanned_by(
|
|
||||||
s,
|
|
||||||
format!("failed to parse request deserializer {:?}", s.value()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
event_attrs.input = Some(input_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if name_value.path == EVENT_OUTPUT {
|
|
||||||
if let syn::Lit::Str(s) = &name_value.lit {
|
|
||||||
let output_type = parse_lit_str(s)
|
|
||||||
.map_err(|_| {
|
|
||||||
ctxt.error_spanned_by(
|
|
||||||
s,
|
|
||||||
format!("failed to parse response deserializer {:?}", s.value()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
event_attrs.output = Some(output_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Meta(Path(word)) => {
|
|
||||||
if word == EVENT_IGNORE && attr.path == EVENT {
|
|
||||||
event_attrs.ignore = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Lit(s) => {
|
|
||||||
ctxt.error_spanned_by(s, "unexpected type in cqrs container attribute");
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
ctxt.error_spanned_by(meta_item, "unexpected type in cqrs container attribute");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(_) => {},
|
|
||||||
});
|
|
||||||
ASTEnumAttrVariant {
|
ASTEnumAttrVariant {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
@ -353,6 +302,101 @@ impl ASTEnumAttrVariant {
|
|||||||
pub fn event_output(&self) -> Option<syn::Path> { self.event_attrs.output.clone() }
|
pub fn event_output(&self) -> Option<syn::Path> { self.event_attrs.output.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_event_attrs_from(
|
||||||
|
ctxt: &Ctxt,
|
||||||
|
variant_attrs: &Vec<syn::Attribute>,
|
||||||
|
enum_attrs: &Vec<syn::Attribute>,
|
||||||
|
) -> EventAttrs {
|
||||||
|
let mut event_attrs = EventAttrs {
|
||||||
|
input: None,
|
||||||
|
output: None,
|
||||||
|
error_ty: None,
|
||||||
|
ignore: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum_attrs
|
||||||
|
.iter()
|
||||||
|
.filter(|attr| {
|
||||||
|
attr.path
|
||||||
|
.segments
|
||||||
|
.iter()
|
||||||
|
.find(|s| s.ident == EVENT_ERR)
|
||||||
|
.is_some()
|
||||||
|
})
|
||||||
|
.for_each(|attr| {
|
||||||
|
if let Ok(NameValue(named_value)) = attr.parse_meta() {
|
||||||
|
if let syn::Lit::Str(s) = named_value.lit {
|
||||||
|
event_attrs.error_ty = Some(s.value());
|
||||||
|
} else {
|
||||||
|
eprintln!("❌ {} should not be empty", EVENT_ERR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("❌ Can not find any {} on attr: {:#?}", EVENT_ERR, attr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut extract_event_attr =
|
||||||
|
|attr: &syn::Attribute, meta_item: &syn::NestedMeta| match &meta_item {
|
||||||
|
Meta(NameValue(name_value)) => {
|
||||||
|
if name_value.path == EVENT_INPUT {
|
||||||
|
if let syn::Lit::Str(s) = &name_value.lit {
|
||||||
|
let input_type = parse_lit_str(s)
|
||||||
|
.map_err(|_| {
|
||||||
|
ctxt.error_spanned_by(
|
||||||
|
s,
|
||||||
|
format!("failed to parse request deserializer {:?}", s.value()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
event_attrs.input = Some(input_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if name_value.path == EVENT_OUTPUT {
|
||||||
|
if let syn::Lit::Str(s) = &name_value.lit {
|
||||||
|
let output_type = parse_lit_str(s)
|
||||||
|
.map_err(|_| {
|
||||||
|
ctxt.error_spanned_by(
|
||||||
|
s,
|
||||||
|
format!(
|
||||||
|
"failed to parse response deserializer {:?}",
|
||||||
|
s.value()
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
event_attrs.output = Some(output_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Meta(Path(word)) => {
|
||||||
|
if word == EVENT_IGNORE && attr.path == EVENT {
|
||||||
|
event_attrs.ignore = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Lit(s) => ctxt.error_spanned_by(s, "unexpected attribute"),
|
||||||
|
_ => ctxt.error_spanned_by(meta_item, "unexpected attribute"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let attr_meta_items_info = variant_attrs
|
||||||
|
.iter()
|
||||||
|
.flat_map(|attr| match get_meta_items(ctxt, attr) {
|
||||||
|
Ok(items) => Some((attr, items)),
|
||||||
|
Err(_) => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<(&syn::Attribute, Vec<syn::NestedMeta>)>>();
|
||||||
|
|
||||||
|
for (attr, nested_metas) in attr_meta_items_info {
|
||||||
|
nested_metas
|
||||||
|
.iter()
|
||||||
|
.for_each(|meta_item| extract_event_attr(attr, meta_item))
|
||||||
|
}
|
||||||
|
|
||||||
|
// eprintln!("😁{:#?}", event_attrs);
|
||||||
|
|
||||||
|
event_attrs
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::NestedMeta>, ()> {
|
pub fn get_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::NestedMeta>, ()> {
|
||||||
if attr.path != PB_ATTRS && attr.path != EVENT {
|
if attr.path != PB_ATTRS && attr.path != EVENT {
|
||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
|
@ -18,6 +18,7 @@ pub const EVENT_INPUT: Symbol = Symbol("input");
|
|||||||
pub const EVENT_OUTPUT: Symbol = Symbol("output");
|
pub const EVENT_OUTPUT: Symbol = Symbol("output");
|
||||||
pub const EVENT_IGNORE: Symbol = Symbol("ignore");
|
pub const EVENT_IGNORE: Symbol = Symbol("ignore");
|
||||||
pub const EVENT: Symbol = Symbol("event");
|
pub const EVENT: Symbol = Symbol("event");
|
||||||
|
pub const EVENT_ERR: Symbol = Symbol("event_err");
|
||||||
|
|
||||||
impl PartialEq<Symbol> for Ident {
|
impl PartialEq<Symbol> for Ident {
|
||||||
fn eq(&self, word: &Symbol) -> bool { self == word.0 }
|
fn eq(&self, word: &Symbol) -> bool { self == word.0 }
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
|
||||||
|
// #[proc_macro_derive(DartEvent, attributes(event_ty))]
|
||||||
pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
|
pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
|
||||||
Ok(TokenStream::default())
|
Ok(TokenStream::default())
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ pub fn derive_proto_buf_enum(input: TokenStream) -> TokenStream {
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(Flowy_Event, attributes(event))]
|
#[proc_macro_derive(Flowy_Event, attributes(event, event_err))]
|
||||||
pub fn derive_dart_event(input: TokenStream) -> TokenStream {
|
pub fn derive_dart_event(input: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(input as DeriveInput);
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
dart_event::expand_enum_derive(&input)
|
dart_event::expand_enum_derive(&input)
|
||||||
|
@ -78,13 +78,6 @@ impl flowy_dispatch::Error for UserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! static_error {
|
|
||||||
($name:ident, $status:expr) => {
|
|
||||||
#[allow(non_snake_case, missing_docs)]
|
|
||||||
pub fn $name() -> ErrorBuilder { ErrorBuilder::new($status) }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ErrorBuilder {
|
pub struct ErrorBuilder {
|
||||||
pub code: UserErrorCode,
|
pub code: UserErrorCode,
|
||||||
pub msg: Option<String>,
|
pub msg: Option<String>,
|
||||||
|
@ -2,6 +2,7 @@ use derive_more::Display;
|
|||||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||||
|
#[event_err = "UserError"]
|
||||||
pub enum UserEvent {
|
pub enum UserEvent {
|
||||||
#[display(fmt = "GetStatus")]
|
#[display(fmt = "GetStatus")]
|
||||||
#[event(output = "UserDetail")]
|
#[event(output = "UserDetail")]
|
||||||
@ -13,6 +14,6 @@ pub enum UserEvent {
|
|||||||
#[event(input = "SignUpRequest", output = "UserDetail")]
|
#[event(input = "SignUpRequest", output = "UserDetail")]
|
||||||
SignUp = 2,
|
SignUp = 2,
|
||||||
#[display(fmt = "SignOut")]
|
#[display(fmt = "SignOut")]
|
||||||
#[event()]
|
#[event(passthrough)]
|
||||||
SignOut = 3,
|
SignOut = 3,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user