class.rs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. use super::*;
  2. #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
  3. #[derive(Encode, Decode, Eq, PartialEq, Default, Clone)]
  4. pub struct Class<
  5. EntityId: Default + BaseArithmetic + Clone + Copy,
  6. ClassId: Default + BaseArithmetic + Clone + Copy,
  7. CuratorGroupId: Ord + Default,
  8. > {
  9. /// Permissions for an instance of a Class.
  10. class_permissions: ClassPermissions<CuratorGroupId>,
  11. /// All properties that have been used on this class across different class schemas.
  12. /// Unlikely to be more than roughly 20 properties per class, often less.
  13. /// For Person, think "height", "weight", etc.
  14. properties: Vec<Property<ClassId>>,
  15. /// All schemas that are available for this class, think v0.0 Person, v.1.0 Person, etc.
  16. schemas: Vec<Schema>,
  17. name: Vec<u8>,
  18. description: Vec<u8>,
  19. /// The maximum number of entities which can be created.
  20. maximum_entities_count: EntityId,
  21. /// The current number of entities which exist.
  22. current_number_of_entities: EntityId,
  23. /// How many entities a given controller may create at most.
  24. default_entity_creation_voucher_upper_bound: EntityId,
  25. }
  26. impl<
  27. EntityId: Default + BaseArithmetic + Clone + Copy,
  28. ClassId: Default + BaseArithmetic + Clone + Copy,
  29. CuratorGroupId: Ord + Default,
  30. > Class<EntityId, ClassId, CuratorGroupId>
  31. {
  32. /// Create new `Class` with provided parameters
  33. pub fn new(
  34. class_permissions: ClassPermissions<CuratorGroupId>,
  35. name: Vec<u8>,
  36. description: Vec<u8>,
  37. maximum_entities_count: EntityId,
  38. default_entity_creation_voucher_upper_bound: EntityId,
  39. ) -> Self {
  40. Self {
  41. class_permissions,
  42. properties: vec![],
  43. schemas: vec![],
  44. name,
  45. description,
  46. maximum_entities_count,
  47. current_number_of_entities: EntityId::zero(),
  48. default_entity_creation_voucher_upper_bound,
  49. }
  50. }
  51. pub fn get_name(&self) -> &[u8] {
  52. &self.name
  53. }
  54. pub fn get_description(&self) -> &[u8] {
  55. &self.description
  56. }
  57. pub fn set_name(&mut self, name: Vec<u8>) {
  58. self.name = name;
  59. }
  60. pub fn set_description(&mut self, description: Vec<u8>) {
  61. self.description = description;
  62. }
  63. /// Used to update `Schema` status under given `schema_index`
  64. pub fn update_schema_status(&mut self, schema_index: SchemaId, schema_status: bool) {
  65. if let Some(schema) = self.schemas.get_mut(schema_index as usize) {
  66. schema.set_status(schema_status);
  67. };
  68. }
  69. /// Used to update `Class` permissions
  70. pub fn update_permissions(&mut self, permissions: ClassPermissions<CuratorGroupId>) {
  71. self.class_permissions = permissions
  72. }
  73. /// Get Class schemas by mutable reference
  74. pub fn get_schemas_mut(&mut self) -> &mut Vec<Schema> {
  75. &mut self.schemas
  76. }
  77. /// Get Class schemas by reference
  78. pub fn get_schemas(&self) -> &Vec<Schema> {
  79. &self.schemas
  80. }
  81. /// Increment number of entities, associated with this class
  82. pub fn increment_entities_count(&mut self) {
  83. self.current_number_of_entities += EntityId::one();
  84. }
  85. /// Decrement number of entities, associated with this class
  86. pub fn decrement_entities_count(&mut self) {
  87. self.current_number_of_entities -= EntityId::one();
  88. }
  89. /// Retrieve `ClassPermissions` by mutable reference
  90. pub fn get_permissions_mut(&mut self) -> &mut ClassPermissions<CuratorGroupId> {
  91. &mut self.class_permissions
  92. }
  93. /// Retrieve `ClassPermissions` by reference
  94. pub fn get_permissions_ref(&self) -> &ClassPermissions<CuratorGroupId> {
  95. &self.class_permissions
  96. }
  97. /// Retrieve `ClassPermissions` by value
  98. pub fn get_permissions(self) -> ClassPermissions<CuratorGroupId> {
  99. self.class_permissions
  100. }
  101. /// Retrieve `Class` properties by value
  102. pub fn get_properties(self) -> Vec<Property<ClassId>> {
  103. self.properties
  104. }
  105. /// Replace `Class` properties with updated_class_properties
  106. pub fn set_properties(&mut self, updated_class_properties: Vec<Property<ClassId>>) {
  107. self.properties = updated_class_properties;
  108. }
  109. /// Get per controller `Class`- specific limit
  110. pub fn get_default_entity_creation_voucher_upper_bound(&self) -> EntityId {
  111. self.default_entity_creation_voucher_upper_bound
  112. }
  113. /// Retrive the maximum entities count, which can be created for given `Class`
  114. pub fn get_maximum_entities_count(&self) -> EntityId {
  115. self.maximum_entities_count
  116. }
  117. /// Set per controller `Class`- specific limit
  118. pub fn set_default_entity_creation_voucher_upper_bound(
  119. &mut self,
  120. new_default_entity_creation_voucher_upper_bound: EntityId,
  121. ) {
  122. self.default_entity_creation_voucher_upper_bound =
  123. new_default_entity_creation_voucher_upper_bound;
  124. }
  125. /// Set the maximum entities count, which can be created for given `Class`
  126. pub fn set_maximum_entities_count(&mut self, maximum_entities_count: EntityId) {
  127. self.maximum_entities_count = maximum_entities_count;
  128. }
  129. /// Ensure `Class` `Schema` under given index exist, return corresponding `Schema`
  130. pub fn ensure_schema_exists<T: Trait>(
  131. &self,
  132. schema_index: SchemaId,
  133. ) -> Result<&Schema, Error<T>> {
  134. self.schemas
  135. .get(schema_index as usize)
  136. .ok_or(Error::<T>::UnknownClassSchemaId)
  137. }
  138. /// Ensure `schema_id` is a valid index of `Class` schemas vector
  139. pub fn ensure_schema_id_exists<T: Trait>(&self, schema_id: SchemaId) -> Result<(), Error<T>> {
  140. ensure!(
  141. schema_id < self.schemas.len() as SchemaId,
  142. Error::<T>::UnknownClassSchemaId
  143. );
  144. Ok(())
  145. }
  146. /// Ensure `Schema`s limit per `Class` not reached
  147. pub fn ensure_schemas_limit_not_reached<T: Trait>(&self) -> Result<(), Error<T>> {
  148. ensure!(
  149. (self.schemas.len() as MaxNumber) < T::MaxNumberOfSchemasPerClass::get(),
  150. Error::<T>::ClassSchemasLimitReached
  151. );
  152. Ok(())
  153. }
  154. /// Ensure properties limit per `Schema` not reached
  155. pub fn ensure_properties_limit_not_reached<T: Trait>(
  156. &self,
  157. new_properties: &[Property<ClassId>],
  158. ) -> Result<(), Error<T>> {
  159. ensure!(
  160. T::MaxNumberOfPropertiesPerSchema::get()
  161. >= (self.properties.len() + new_properties.len()) as MaxNumber,
  162. Error::<T>::SchemaPropertiesLimitReached
  163. );
  164. Ok(())
  165. }
  166. /// Ensure `Class` specific entities limit not reached
  167. pub fn ensure_maximum_entities_count_limit_not_reached<T: Trait>(
  168. &self,
  169. ) -> Result<(), Error<T>> {
  170. ensure!(
  171. self.current_number_of_entities < self.maximum_entities_count,
  172. Error::<T>::NumberOfEntitiesPerClassLimitReached
  173. );
  174. Ok(())
  175. }
  176. /// Ensure `Property` under given `PropertyId` is unlocked from actor with given `EntityAccessLevel`
  177. /// return corresponding `Property` by value
  178. pub fn ensure_class_property_type_unlocked_from<T: Trait>(
  179. self,
  180. in_class_schema_property_id: PropertyId,
  181. entity_access_level: EntityAccessLevel,
  182. ) -> Result<Property<ClassId>, Error<T>> {
  183. // Ensure property values were not locked on Class level
  184. self.ensure_property_values_unlocked()?;
  185. // Get class-level information about this `Property`
  186. let class_property = self
  187. .properties
  188. .get(in_class_schema_property_id as usize)
  189. // Throw an error if a property was not found on class
  190. // by an in-class index of a property.
  191. .ok_or(Error::<T>::ClassPropertyNotFound)?;
  192. // Ensure Property is unlocked from Actor with given EntityAccessLevel
  193. class_property.ensure_unlocked_from::<T>(entity_access_level)?;
  194. Ok(class_property.clone())
  195. }
  196. /// Ensure property values were not locked on `Class` level
  197. pub fn ensure_property_values_unlocked<T: Trait>(&self) -> Result<(), Error<T>> {
  198. ensure!(
  199. !self
  200. .get_permissions_ref()
  201. .all_entity_property_values_locked(),
  202. Error::<T>::AllPropertiesWereLockedOnClassLevel
  203. );
  204. Ok(())
  205. }
  206. }