map.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. use std::borrow::Cow;
  2. use proc_macro2::TokenStream;
  3. use quote::quote;
  4. use syn::Result;
  5. use crate::args::name_arg;
  6. use syn::ItemStatic;
  7. pub(crate) struct Map {
  8. item: ItemStatic,
  9. name: String,
  10. }
  11. impl Map {
  12. pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Map> {
  13. let mut args = syn::parse2(attrs)?;
  14. let item: ItemStatic = syn::parse2(item)?;
  15. let name = name_arg(&mut args)?.unwrap_or_else(|| item.ident.to_string());
  16. Ok(Map { item, name })
  17. }
  18. pub(crate) fn expand(&self) -> Result<TokenStream> {
  19. let section_name: Cow<'_, _> = "maps".to_string().into();
  20. let name = &self.name;
  21. let item = &self.item;
  22. Ok(quote! {
  23. #[link_section = #section_name]
  24. #[export_name = #name]
  25. #item
  26. })
  27. }
  28. }
  29. #[cfg(test)]
  30. mod tests {
  31. use super::*;
  32. use syn::parse_quote;
  33. #[test]
  34. fn test_map_with_name() {
  35. let map = Map::parse(
  36. parse_quote!(name = "foo"),
  37. parse_quote!(
  38. static BAR: HashMap<&'static str, u32> = HashMap::new();
  39. ),
  40. )
  41. .unwrap();
  42. let expanded = map.expand().unwrap();
  43. let expected = quote!(
  44. #[link_section = "maps"]
  45. #[export_name = "foo"]
  46. static BAR: HashMap<&'static str, u32> = HashMap::new();
  47. );
  48. assert_eq!(expected.to_string(), expanded.to_string());
  49. }
  50. #[test]
  51. fn test_map_no_name() {
  52. let map = Map::parse(
  53. parse_quote!(),
  54. parse_quote!(
  55. static BAR: HashMap<&'static str, u32> = HashMap::new();
  56. ),
  57. )
  58. .unwrap();
  59. let expanded = map.expand().unwrap();
  60. let expected = quote!(
  61. #[link_section = "maps"]
  62. #[export_name = "BAR"]
  63. static BAR: HashMap<&'static str, u32> = HashMap::new();
  64. );
  65. assert_eq!(expected.to_string(), expanded.to_string());
  66. }
  67. }