runtime.rs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use proc_macro2::TokenStream;
  5. use quote::{quote, ToTokens};
  6. use syn::parse::{Parse, ParseStream};
  7. use syn::{
  8. parse_quote, DeriveInput, Error, GenericParam, Ident, ItemTrait, ItemType, Token, Type, TypeParam,
  9. };
  10. #[derive(Clone)]
  11. pub(crate) enum Input {
  12. Derive(DeriveInput),
  13. Trait(ItemTrait),
  14. Type(ItemType),
  15. }
  16. impl Parse for Input {
  17. fn parse(input: ParseStream) -> syn::Result<Self> {
  18. input
  19. .parse::<DeriveInput>()
  20. .map(Self::Derive)
  21. .or_else(|_| input.parse().map(Self::Trait))
  22. .or_else(|_| input.parse().map(Self::Type))
  23. .map_err(|_| {
  24. Error::new(
  25. input.span(),
  26. "default_runtime only supports `struct`, `enum`, `type`, or `trait` definitions",
  27. )
  28. })
  29. }
  30. }
  31. impl Input {
  32. fn last_param_mut(&mut self) -> Option<&mut GenericParam> {
  33. match self {
  34. Input::Derive(d) => d.generics.params.last_mut(),
  35. Input::Trait(t) => t.generics.params.last_mut(),
  36. Input::Type(t) => t.generics.params.last_mut(),
  37. }
  38. }
  39. }
  40. impl ToTokens for Input {
  41. fn to_tokens(&self, tokens: &mut TokenStream) {
  42. match self {
  43. Input::Derive(d) => d.to_tokens(tokens),
  44. Input::Trait(t) => t.to_tokens(tokens),
  45. Input::Type(t) => t.to_tokens(tokens),
  46. }
  47. }
  48. }
  49. /// The default runtime type to enable when the provided feature is enabled.
  50. pub(crate) struct Attributes {
  51. default_type: Type,
  52. feature: Ident,
  53. }
  54. impl Parse for Attributes {
  55. fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
  56. let default_type = input.parse()?;
  57. input.parse::<Token![,]>()?;
  58. Ok(Attributes {
  59. default_type,
  60. feature: input.parse()?,
  61. })
  62. }
  63. }
  64. pub(crate) fn default_runtime(attributes: Attributes, input: Input) -> TokenStream {
  65. // create a new copy to manipulate for the wry feature flag
  66. let mut wry = input.clone();
  67. let wry_runtime = wry
  68. .last_param_mut()
  69. .expect("default_runtime requires the item to have at least 1 generic parameter");
  70. // set the default value of the last generic parameter to the provided runtime type
  71. match wry_runtime {
  72. GenericParam::Type(
  73. param @ TypeParam {
  74. eq_token: None,
  75. default: None,
  76. ..
  77. },
  78. ) => {
  79. param.eq_token = Some(parse_quote!(=));
  80. param.default = Some(attributes.default_type);
  81. }
  82. _ => {
  83. panic!("DefaultRuntime requires the last parameter to not have a default value")
  84. }
  85. };
  86. let feature = attributes.feature.to_string();
  87. quote!(
  88. #[cfg(feature = #feature)]
  89. #wry
  90. #[cfg(not(feature = #feature))]
  91. #input
  92. )
  93. }