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) => {
|
||||
// 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>(
|
||||
cx: &Ctxt,
|
||||
variants: &'a Punctuated<syn::Variant, Token![,]>,
|
||||
enum_attrs: &Vec<syn::Attribute>,
|
||||
) -> Vec<ASTEnumVariant<'a>> {
|
||||
variants
|
||||
.iter()
|
||||
.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);
|
||||
Some(ASTEnumVariant {
|
||||
|
@ -5,6 +5,7 @@ use syn::{
|
||||
self,
|
||||
parse::{self, Parse},
|
||||
Meta::{List, NameValue, Path},
|
||||
NestedMeta,
|
||||
NestedMeta::{Lit, Meta},
|
||||
};
|
||||
|
||||
@ -260,6 +261,7 @@ pub enum Default {
|
||||
pub struct EventAttrs {
|
||||
input: Option<syn::Path>,
|
||||
output: Option<syn::Path>,
|
||||
error_ty: Option<String>,
|
||||
pub ignore: bool,
|
||||
}
|
||||
|
||||
@ -271,7 +273,7 @@ pub struct 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 mut value = String::new();
|
||||
if variant.discriminant.is_some() {
|
||||
@ -287,60 +289,7 @@ impl ASTEnumAttrVariant {
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
let mut event_attrs = EventAttrs {
|
||||
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(_) => {},
|
||||
});
|
||||
let event_attrs = get_event_attrs_from(ctxt, &variant.attrs, enum_attrs);
|
||||
ASTEnumAttrVariant {
|
||||
name,
|
||||
value,
|
||||
@ -353,6 +302,101 @@ impl ASTEnumAttrVariant {
|
||||
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>, ()> {
|
||||
if attr.path != PB_ATTRS && attr.path != EVENT {
|
||||
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_IGNORE: Symbol = Symbol("ignore");
|
||||
pub const EVENT: Symbol = Symbol("event");
|
||||
pub const EVENT_ERR: Symbol = Symbol("event_err");
|
||||
|
||||
impl PartialEq<Symbol> for Ident {
|
||||
fn eq(&self, word: &Symbol) -> bool { self == word.0 }
|
||||
|
@ -1,4 +1,6 @@
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
// #[proc_macro_derive(DartEvent, attributes(event_ty))]
|
||||
pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
|
||||
Ok(TokenStream::default())
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ pub fn derive_proto_buf_enum(input: TokenStream) -> TokenStream {
|
||||
.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 {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
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 code: UserErrorCode,
|
||||
pub msg: Option<String>,
|
||||
|
@ -2,6 +2,7 @@ use derive_more::Display;
|
||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
#[event_err = "UserError"]
|
||||
pub enum UserEvent {
|
||||
#[display(fmt = "GetStatus")]
|
||||
#[event(output = "UserDetail")]
|
||||
@ -13,6 +14,6 @@ pub enum UserEvent {
|
||||
#[event(input = "SignUpRequest", output = "UserDetail")]
|
||||
SignUp = 2,
|
||||
#[display(fmt = "SignOut")]
|
||||
#[event()]
|
||||
#[event(passthrough)]
|
||||
SignOut = 3,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user