aboutsummaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
Diffstat (limited to 'macros')
-rw-r--r--macros/src/declare_interface_args.rs130
1 files changed, 124 insertions, 6 deletions
diff --git a/macros/src/declare_interface_args.rs b/macros/src/declare_interface_args.rs
index 529a114..bc15d2e 100644
--- a/macros/src/declare_interface_args.rs
+++ b/macros/src/declare_interface_args.rs
@@ -1,4 +1,4 @@
-use syn::parse::{Parse, ParseStream, Result};
+use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::{Token, TypePath};
@@ -16,7 +16,7 @@ pub struct DeclareInterfaceArgs
impl Parse for DeclareInterfaceArgs
{
- fn parse(input: ParseStream) -> Result<Self>
+ fn parse(input: ParseStream) -> syn::Result<Self>
{
let implementation: TypePath = input.parse()?;
@@ -30,12 +30,11 @@ impl Parse for DeclareInterfaceArgs
let flags = Punctuated::<MacroFlag, Token![,]>::parse_terminated(input)?;
for flag in &flags {
- let flag_str = flag.flag.to_string();
+ let flag_name = flag.flag.to_string();
- if !DECLARE_INTERFACE_FLAGS.contains(&flag_str.as_str()) {
+ if !DECLARE_INTERFACE_FLAGS.contains(&flag_name.as_str()) {
return Err(input.error(format!(
- "Unknown flag '{}'. Expected one of [ {} ]",
- flag_str,
+ "Unknown flag '{flag_name}'. Expected one of [ {} ]",
DECLARE_INTERFACE_FLAGS.join(",")
)));
}
@@ -62,3 +61,122 @@ impl Parse for DeclareInterfaceArgs
})
}
}
+
+#[cfg(test)]
+mod tests
+{
+ use std::error::Error;
+
+ use proc_macro2::Span;
+ use quote::{format_ident, quote};
+ use syn::{parse2, LitBool};
+
+ use super::*;
+ use crate::test_utils;
+
+ #[test]
+ fn can_parse_with_no_flags() -> Result<(), Box<dyn Error>>
+ {
+ let input_args = quote! {
+ Foo -> IFoo
+ };
+
+ let decl_interface_args = parse2::<DeclareInterfaceArgs>(input_args)?;
+
+ assert_eq!(
+ decl_interface_args.implementation,
+ TypePath {
+ qself: None,
+ path: test_utils::create_path(&[test_utils::create_path_segment(
+ format_ident!("Foo"),
+ &[]
+ )])
+ }
+ );
+
+ assert_eq!(
+ decl_interface_args.interface,
+ TypePath {
+ qself: None,
+ path: test_utils::create_path(&[test_utils::create_path_segment(
+ format_ident!("IFoo"),
+ &[]
+ )])
+ }
+ );
+
+ assert!(decl_interface_args.flags.is_empty());
+
+ Ok(())
+ }
+
+ #[test]
+ fn can_parse_with_flags() -> Result<(), Box<dyn Error>>
+ {
+ let input_args = quote! {
+ Foobar -> IFoobar, async = true
+ };
+
+ let decl_interface_args = parse2::<DeclareInterfaceArgs>(input_args)?;
+
+ assert_eq!(
+ decl_interface_args.implementation,
+ TypePath {
+ qself: None,
+ path: test_utils::create_path(&[test_utils::create_path_segment(
+ format_ident!("Foobar"),
+ &[]
+ )])
+ }
+ );
+
+ assert_eq!(
+ decl_interface_args.interface,
+ TypePath {
+ qself: None,
+ path: test_utils::create_path(&[test_utils::create_path_segment(
+ format_ident!("IFoobar"),
+ &[]
+ )])
+ }
+ );
+
+ assert_eq!(
+ decl_interface_args.flags,
+ Punctuated::from_iter(vec![MacroFlag {
+ flag: format_ident!("async"),
+ is_on: LitBool::new(true, Span::call_site())
+ }])
+ );
+
+ Ok(())
+ }
+
+ #[test]
+ fn cannot_parse_with_invalid_flag()
+ {
+ let input_args = quote! {
+ Foobar -> IFoobar, xyz = false, async = true
+ };
+
+ assert!(matches!(parse2::<DeclareInterfaceArgs>(input_args), Err(_)));
+ }
+
+ #[test]
+ fn cannot_parse_with_duplicate_flag()
+ {
+ assert!(matches!(
+ parse2::<DeclareInterfaceArgs>(quote! {
+ Foobar -> IFoobar, async = true, async = true
+ }),
+ Err(_)
+ ));
+
+ assert!(matches!(
+ parse2::<DeclareInterfaceArgs>(quote! {
+ Foobar -> IFoobar, async = true, async = false
+ }),
+ Err(_)
+ ));
+ }
+}