plugin.rs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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::BTreeMap,
  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. /// An enum used to do serde operations with a list or a single capability.
  49. #[derive(Serialize, Deserialize)]
  50. #[serde(untagged)]
  51. pub enum CapabilityOrList {
  52. /// A single capability.
  53. Single(Capability),
  54. /// A list of capabilities.
  55. List(Vec<Capability>),
  56. }
  57. /// Plugin manifest.
  58. #[derive(Debug, Serialize, Deserialize)]
  59. pub struct Manifest {
  60. /// Plugin name.
  61. #[serde(skip_serializing_if = "String::is_empty", default)]
  62. pub plugin: String,
  63. /// Default capability.
  64. pub default_capability: Option<Capability>,
  65. /// List of capabilities defined by the plugin.
  66. pub capabilities: Vec<Capability>,
  67. /// List of features defined by the plugin.
  68. pub features: Vec<String>,
  69. /// Scope types.
  70. pub scope_type: Vec<ScopeType>,
  71. }
  72. impl Manifest {
  73. /// Creates a new empty plugin manifest.
  74. pub fn new(plugin: impl Into<String>) -> Self {
  75. Self {
  76. plugin: plugin.into(),
  77. default_capability: None,
  78. capabilities: Vec::new(),
  79. features: Vec::new(),
  80. scope_type: Vec::new(),
  81. }
  82. }
  83. /// Sets the plugin's default capability set from a JSON string.
  84. pub fn default_capability_json(mut self, default_capability: impl AsRef<str>) -> Self {
  85. let mut capability: Capability = serde_json::from_str(default_capability.as_ref())
  86. .expect("failed to deserialize default capability");
  87. assert!(
  88. capability.id.is_empty(),
  89. "default capability cannot have an identifier"
  90. );
  91. capability.id = DEFAULT_CAPABILITY_ID.into();
  92. self.default_capability.replace(capability);
  93. self
  94. }
  95. /// Appends a capability from a JSON string. The JSON can also include an array of capabilities instead of a single one. See [`Capability`].
  96. pub fn capability_json(self, capability: impl AsRef<str>) -> Self {
  97. let capability =
  98. serde_json::from_str(capability.as_ref()).expect("failed to deserialize default capability");
  99. match capability {
  100. CapabilityOrList::Single(cap) => self.capability(cap),
  101. CapabilityOrList::List(l) => self.capabilities(l),
  102. }
  103. }
  104. /// Appends a [`Capability`].
  105. pub fn capability(mut self, capability: Capability) -> Self {
  106. assert!(
  107. !capability.id.is_empty(),
  108. "capability must have an identifier"
  109. );
  110. self.capabilities.push(capability);
  111. self
  112. }
  113. /// Appends the given list of capabilities. See [`Self::capability`].
  114. pub fn capabilities<I: IntoIterator<Item = Capability>>(mut self, capabilities: I) -> Self {
  115. for capability in capabilities {
  116. self = self.capability(capability);
  117. }
  118. self
  119. }
  120. /// Appends the given feature on the list of plugin's features.
  121. pub fn feature(mut self, feature: impl Into<String>) -> Self {
  122. self.features.push(feature.into());
  123. self
  124. }
  125. /// Appends the given list of features.
  126. pub fn features<I: IntoIterator<Item = S>, S: Into<String>>(mut self, features: I) -> Self {
  127. for feature in features {
  128. self = self.feature(feature);
  129. }
  130. self
  131. }
  132. /// Appends the given scope type.
  133. pub fn scope_type(mut self, ty: ScopeType) -> Self {
  134. self.scope_type.push(ty);
  135. self
  136. }
  137. }
  138. /// A collection mapping a plugin name to its manifest.
  139. #[derive(Debug, Default, Deserialize, Serialize)]
  140. pub struct ManifestMap(BTreeMap<String, Manifest>);
  141. impl Deref for ManifestMap {
  142. type Target = BTreeMap<String, Manifest>;
  143. fn deref(&self) -> &Self::Target {
  144. &self.0
  145. }
  146. }
  147. impl DerefMut for ManifestMap {
  148. fn deref_mut(&mut self) -> &mut Self::Target {
  149. &mut self.0
  150. }
  151. }
  152. impl From<BTreeMap<String, Manifest>> for ManifestMap {
  153. fn from(value: BTreeMap<String, Manifest>) -> Self {
  154. Self(value)
  155. }
  156. }
  157. impl ManifestMap {
  158. /// Finds the capability with the given identifier.
  159. pub fn find_capability(&self, id: &str) -> Vec<(String, Capability)> {
  160. let mut capabilities = Vec::new();
  161. for (plugin, manifest) in &self.0 {
  162. if id == format!("{DEFAULT_CAPABILITY_ID}-{plugin}") {
  163. capabilities.push((
  164. plugin.clone(),
  165. manifest.default_capability.clone().unwrap_or_default(),
  166. ));
  167. }
  168. for capability in &manifest.capabilities {
  169. if capability.id == id {
  170. capabilities.push((plugin.clone(), capability.clone()));
  171. }
  172. }
  173. }
  174. capabilities
  175. }
  176. }