mirror of
https://github.com/qemu/qemu.git
synced 2025-08-16 06:43:21 +00:00
rust: qemu_api_macros: make pattern matching more readable and efficient
"let ... else" is useful when visiting syntax trees; it avoids multiple levels of indentation and places the error close to the pattern. While at it, use "ref" to avoid moving the syntax tree objects. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
51209c2aed
commit
465a4b80e2
@ -16,50 +16,41 @@ fn get_fields<'a>(
|
|||||||
input: &'a DeriveInput,
|
input: &'a DeriveInput,
|
||||||
msg: &str,
|
msg: &str,
|
||||||
) -> Result<&'a Punctuated<Field, Comma>, MacroError> {
|
) -> Result<&'a Punctuated<Field, Comma>, MacroError> {
|
||||||
if let Data::Struct(s) = &input.data {
|
let Data::Struct(ref s) = &input.data else {
|
||||||
if let Fields::Named(fs) = &s.fields {
|
return Err(MacroError::Message(
|
||||||
Ok(&fs.named)
|
|
||||||
} else {
|
|
||||||
Err(MacroError::Message(
|
|
||||||
format!("Named fields required for {}", msg),
|
|
||||||
input.ident.span(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(MacroError::Message(
|
|
||||||
format!("Struct required for {}", msg),
|
format!("Struct required for {}", msg),
|
||||||
input.ident.span(),
|
input.ident.span(),
|
||||||
))
|
));
|
||||||
}
|
};
|
||||||
|
let Fields::Named(ref fs) = &s.fields else {
|
||||||
|
return Err(MacroError::Message(
|
||||||
|
format!("Named fields required for {}", msg),
|
||||||
|
input.ident.span(),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
Ok(&fs.named)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_unnamed_field<'a>(input: &'a DeriveInput, msg: &str) -> Result<&'a Field, MacroError> {
|
fn get_unnamed_field<'a>(input: &'a DeriveInput, msg: &str) -> Result<&'a Field, MacroError> {
|
||||||
if let Data::Struct(s) = &input.data {
|
let Data::Struct(ref s) = &input.data else {
|
||||||
let unnamed = match &s.fields {
|
return Err(MacroError::Message(
|
||||||
Fields::Unnamed(FieldsUnnamed {
|
|
||||||
unnamed: ref fields,
|
|
||||||
..
|
|
||||||
}) => fields,
|
|
||||||
_ => {
|
|
||||||
return Err(MacroError::Message(
|
|
||||||
format!("Tuple struct required for {}", msg),
|
|
||||||
s.fields.span(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if unnamed.len() != 1 {
|
|
||||||
return Err(MacroError::Message(
|
|
||||||
format!("A single field is required for {}", msg),
|
|
||||||
s.fields.span(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(&unnamed[0])
|
|
||||||
} else {
|
|
||||||
Err(MacroError::Message(
|
|
||||||
format!("Struct required for {}", msg),
|
format!("Struct required for {}", msg),
|
||||||
input.ident.span(),
|
input.ident.span(),
|
||||||
))
|
));
|
||||||
|
};
|
||||||
|
let Fields::Unnamed(FieldsUnnamed { ref unnamed, .. }) = &s.fields else {
|
||||||
|
return Err(MacroError::Message(
|
||||||
|
format!("Tuple struct required for {}", msg),
|
||||||
|
s.fields.span(),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
if unnamed.len() != 1 {
|
||||||
|
return Err(MacroError::Message(
|
||||||
|
format!("A single field is required for {}", msg),
|
||||||
|
s.fields.span(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
Ok(&unnamed[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> {
|
fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> {
|
||||||
@ -210,20 +201,19 @@ fn get_repr_uN(input: &DeriveInput, msg: &str) -> Result<Path, MacroError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_variants(input: &DeriveInput) -> Result<&Punctuated<Variant, Comma>, MacroError> {
|
fn get_variants(input: &DeriveInput) -> Result<&Punctuated<Variant, Comma>, MacroError> {
|
||||||
if let Data::Enum(e) = &input.data {
|
let Data::Enum(ref e) = &input.data else {
|
||||||
if let Some(v) = e.variants.iter().find(|v| v.fields != Fields::Unit) {
|
return Err(MacroError::Message(
|
||||||
return Err(MacroError::Message(
|
|
||||||
"Cannot derive TryInto for enum with non-unit variants.".to_string(),
|
|
||||||
v.fields.span(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(&e.variants)
|
|
||||||
} else {
|
|
||||||
Err(MacroError::Message(
|
|
||||||
"Cannot derive TryInto for union or struct.".to_string(),
|
"Cannot derive TryInto for union or struct.".to_string(),
|
||||||
input.ident.span(),
|
input.ident.span(),
|
||||||
))
|
));
|
||||||
|
};
|
||||||
|
if let Some(v) = e.variants.iter().find(|v| v.fields != Fields::Unit) {
|
||||||
|
return Err(MacroError::Message(
|
||||||
|
"Cannot derive TryInto for enum with non-unit variants.".to_string(),
|
||||||
|
v.fields.span(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
Ok(&e.variants)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip::macros(quote)]
|
#[rustfmt::skip::macros(quote)]
|
||||||
|
Loading…
Reference in New Issue
Block a user