plugin.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright 2019-2023 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! Plugin manifest types.
  5. use serde::{Deserialize, Serialize};
  6. use std::{
  7. collections::HashMap,
  8. ops::{Deref, DerefMut},
  9. };
  10. const DEFAULT_CAPABILITY_ID: &str = "default";
  11. /// Scope type definition.
  12. #[derive(Debug, Serialize, Deserialize)]
  13. pub enum ScopeType {
  14. /// String type.
  15. String,
  16. }
  17. /// Scope of a given capability.
  18. #[derive(Debug, Clone, Default, Serialize, Deserialize)]
  19. pub struct CapabilityScope {
  20. /// Explicitly allow something.
  21. #[serde(default)]
  22. pub allowed: Vec<serde_json::Value>,
  23. /// Explicitly deny something. Takes precedence over [`Self::allowed`].
  24. #[serde(default)]
  25. pub blocked: Vec<serde_json::Value>,
  26. }
  27. /// A capability defines a set of features and scope enabled for the plugin.
  28. #[derive(Debug, Clone, Default, Serialize, Deserialize)]
  29. pub struct Capability {
  30. /// The identifier of the capability. Must be unique.
  31. #[serde(default)]
  32. pub id: String,
  33. /// The component this capability refers to.
  34. ///
  35. /// Currently the possible values are plugin names.
  36. ///
  37. /// When no value is set, it referes to the application itself.
  38. pub component: Option<String>,
  39. /// Describes the capability in a human readable format.
  40. pub description: String,
  41. /// List of features enabled by this capability.
  42. #[serde(default)]
  43. pub features: Vec<String>,
  44. /// Scope defined by this capability. Only applies to the given features.
  45. #[serde(default)]
  46. pub scope: CapabilityScope,
  47. }
  48. #[derive(Serialize, Deserialize)]
  49. #[serde(untagged)]
  50. enum CapabilityOrList {
  51. Single(Capability),
  52. List(Vec<Capability>),
  53. }
  54. /// Plugin manifest.
  55. #[derive(Debug, Serialize, Deserialize)]
  56. pub struct Manifest {
  57. /// Plugin name.
  58. #[serde(skip_serializing_if = "String::is_empty", default)]
  59. pub plugin: String,
  60. /// Default capability.
  61. pub default_capability: Option<Capability>,
  62. /// List of capabilities defined by the plugin.
  63. pub capabilities: Vec<Capability>,
  64. /// List of features defined by the plugin.
  65. pub features: Vec<String>,
  66. /// Scope types.
  67. pub scope_type: Vec<ScopeType>,
  68. }
  69. impl Manifest {
  70. /// Creates a new empty plugin manifest.
  71. pub fn new(plugin: impl Into<String>) -> Self {
  72. Self {
  73. plugin: plugin.into(),
  74. default_capability: None,
  75. capabilities: Vec::new(),
  76. features: Vec::new(),
  77. scope_type: Vec::new(),
  78. }
  79. }
  80. /// Sets the plugin's default capability set from a JSON string.
  81. pub fn default_capability_json(mut self, default_capability: impl AsRef<str>) -> Self {
  82. let mut capability: Capability = serde_json::from_str(default_capability.as_ref())
  83. .expect("failed to deserialize default capability");
  84. assert!(
  85. capability.id.is_empty(),
  86. "default capability cannot have an identifier"
  87. );
  88. capability.id = DEFAULT_CAPABILITY_ID.into();
  89. self.default_capability.replace(capability);
  90. self
  91. }
  92. /// Appends a capability from a JSON string. The JSON can also include an array of capabilities instead of a single one. See [`Capability`].
  93. pub fn capability_json(self, capability: impl AsRef<str>) -> Self {
  94. let capability =
  95. serde_json::from_str(capability.as_ref()).expect("failed to deserialize default capability");
  96. match capability {
  97. CapabilityOrList::Single(cap) => self.capability(cap),
  98. CapabilityOrList::List(l) => self.capabilities(l),
  99. }
  100. }
  101. /// Appends a [`Capability`].
  102. pub fn capability(mut self, capability: Capability) -> Self {
  103. assert!(
  104. !capability.id.is_empty(),
  105. "capability must have an identifier"
  106. );
  107. self.capabilities.push(capability);
  108. self
  109. }
  110. /// Appends the given list of capabilities. See [`Self::capability`].
  111. pub fn capabilities<I: IntoIterator<Item = Capability>>(mut self, capabilities: I) -> Self {
  112. for capability in capabilities {
  113. self = self.capability(capability);
  114. }
  115. self
  116. }
  117. /// Appends the given feature on the list of plugin's features.
  118. pub fn feature(mut self, feature: impl Into<String>) -> Self {
  119. self.features.push(feature.into());
  120. self
  121. }
  122. /// Appends the given list of features.
  123. pub fn features<I: IntoIterator<Item = S>, S: Into<String>>(mut self, features: I) -> Self {
  124. for feature in features {
  125. self = self.feature(feature);
  126. }
  127. self
  128. }
  129. /// Appends the given scope type.
  130. pub fn scope_type(mut self, ty: ScopeType) -> Self {
  131. self.scope_type.push(ty);
  132. self
  133. }
  134. }
  135. /// A collection mapping a plugin name to its manifest.
  136. #[derive(Debug, Default, Deserialize, Serialize)]
  137. pub struct ManifestMap(HashMap<String, Manifest>);
  138. impl Deref for ManifestMap {
  139. type Target = HashMap<String, Manifest>;
  140. fn deref(&self) -> &Self::Target {
  141. &self.0
  142. }
  143. }
  144. impl DerefMut for ManifestMap {
  145. fn deref_mut(&mut self) -> &mut Self::Target {
  146. &mut self.0
  147. }
  148. }
  149. impl From<HashMap<String, Manifest>> for ManifestMap {
  150. fn from(value: HashMap<String, Manifest>) -> Self {
  151. Self(value)
  152. }
  153. }
  154. impl ManifestMap {
  155. /// Finds the capability with the given identifier.
  156. pub fn find_capability(&self, id: &str) -> Vec<(String, Capability)> {
  157. let mut capabilities = Vec::new();
  158. for (plugin, manifest) in &self.0 {
  159. if id == format!("{DEFAULT_CAPABILITY_ID}-{plugin}") {
  160. capabilities.push((
  161. plugin.clone(),
  162. manifest.default_capability.clone().unwrap_or_default(),
  163. ));
  164. }
  165. for capability in &manifest.capabilities {
  166. if capability.id == id {
  167. capabilities.push((plugin.clone(), capability.clone()));
  168. }
  169. }
  170. }
  171. capabilities
  172. }
  173. }