grid_rev.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. use crate::GridBlockRevision;
  2. use bytes::Bytes;
  3. use indexmap::IndexMap;
  4. use nanoid::nanoid;
  5. use serde::{Deserialize, Serialize};
  6. use std::sync::Arc;
  7. pub fn gen_grid_id() -> String {
  8. // nanoid calculator https://zelark.github.io/nano-id-cc/
  9. nanoid!(10)
  10. }
  11. pub fn gen_block_id() -> String {
  12. nanoid!(10)
  13. }
  14. pub fn gen_field_id() -> String {
  15. nanoid!(6)
  16. }
  17. #[derive(Debug, Clone, Default, Serialize, Deserialize)]
  18. pub struct GridRevision {
  19. pub grid_id: String,
  20. pub fields: Vec<Arc<FieldRevision>>,
  21. pub blocks: Vec<Arc<GridBlockMetaRevision>>,
  22. }
  23. impl GridRevision {
  24. pub fn new(grid_id: &str) -> Self {
  25. Self {
  26. grid_id: grid_id.to_owned(),
  27. fields: vec![],
  28. blocks: vec![],
  29. }
  30. }
  31. pub fn from_build_context(
  32. grid_id: &str,
  33. field_revs: Vec<Arc<FieldRevision>>,
  34. block_metas: Vec<GridBlockMetaRevision>,
  35. ) -> Self {
  36. Self {
  37. grid_id: grid_id.to_owned(),
  38. fields: field_revs,
  39. blocks: block_metas.into_iter().map(Arc::new).collect(),
  40. }
  41. }
  42. }
  43. #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
  44. pub struct GridBlockMetaRevision {
  45. pub block_id: String,
  46. pub start_row_index: i32,
  47. pub row_count: i32,
  48. }
  49. impl GridBlockMetaRevision {
  50. pub fn len(&self) -> i32 {
  51. self.row_count
  52. }
  53. pub fn is_empty(&self) -> bool {
  54. self.row_count == 0
  55. }
  56. }
  57. impl GridBlockMetaRevision {
  58. pub fn new() -> Self {
  59. GridBlockMetaRevision {
  60. block_id: gen_block_id(),
  61. ..Default::default()
  62. }
  63. }
  64. }
  65. pub struct GridBlockMetaRevisionChangeset {
  66. pub block_id: String,
  67. pub start_row_index: Option<i32>,
  68. pub row_count: Option<i32>,
  69. }
  70. impl GridBlockMetaRevisionChangeset {
  71. pub fn from_row_count(block_id: String, row_count: i32) -> Self {
  72. Self {
  73. block_id,
  74. start_row_index: None,
  75. row_count: Some(row_count),
  76. }
  77. }
  78. }
  79. #[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
  80. pub struct FieldRevision {
  81. pub id: String,
  82. pub name: String,
  83. pub desc: String,
  84. #[serde(rename = "field_type")]
  85. pub ty: FieldTypeRevision,
  86. pub frozen: bool,
  87. pub visibility: bool,
  88. pub width: i32,
  89. /// type_options contains key/value pairs
  90. /// key: id of the FieldType
  91. /// value: type-option data that can be parsed into specified TypeOptionStruct.
  92. ///
  93. /// For example, CheckboxTypeOption, MultiSelectTypeOption etc.
  94. #[serde(with = "indexmap::serde_seq")]
  95. pub type_options: IndexMap<String, String>,
  96. #[serde(default = "DEFAULT_IS_PRIMARY")]
  97. pub is_primary: bool,
  98. }
  99. impl AsRef<FieldRevision> for FieldRevision {
  100. fn as_ref(&self) -> &FieldRevision {
  101. self
  102. }
  103. }
  104. const DEFAULT_IS_PRIMARY: fn() -> bool = || false;
  105. impl FieldRevision {
  106. pub fn new<T: Into<FieldTypeRevision>>(
  107. name: &str,
  108. desc: &str,
  109. field_type: T,
  110. width: i32,
  111. is_primary: bool,
  112. ) -> Self {
  113. Self {
  114. id: gen_field_id(),
  115. name: name.to_string(),
  116. desc: desc.to_string(),
  117. ty: field_type.into(),
  118. frozen: false,
  119. visibility: true,
  120. width,
  121. type_options: Default::default(),
  122. is_primary,
  123. }
  124. }
  125. pub fn insert_type_option<T>(&mut self, type_option: &T)
  126. where
  127. T: TypeOptionDataSerializer + ?Sized,
  128. {
  129. let id = self.ty.to_string();
  130. self.type_options.insert(id, type_option.json_str());
  131. }
  132. pub fn get_type_option<T: TypeOptionDataDeserializer>(&self, field_type_rev: FieldTypeRevision) -> Option<T> {
  133. let id = field_type_rev.to_string();
  134. self.type_options.get(&id).map(|s| T::from_json_str(s))
  135. }
  136. pub fn insert_type_option_str(&mut self, field_type: &FieldTypeRevision, json_str: String) {
  137. let id = field_type.to_string();
  138. self.type_options.insert(id, json_str);
  139. }
  140. pub fn get_type_option_str<T: Into<FieldTypeRevision>>(&self, field_type: T) -> Option<String> {
  141. let field_type_rev = field_type.into();
  142. let id = field_type_rev.to_string();
  143. self.type_options.get(&id).map(|s| s.to_owned())
  144. }
  145. }
  146. /// The macro [impl_type_option] will implement the [TypeOptionDataSerializer] for the type that
  147. /// supports the serde trait and the TryInto<Bytes> trait.
  148. pub trait TypeOptionDataSerializer {
  149. fn json_str(&self) -> String;
  150. fn protobuf_bytes(&self) -> Bytes;
  151. }
  152. /// The macro [impl_type_option] will implement the [TypeOptionDataDeserializer] for the type that
  153. /// supports the serde trait and the TryFrom<Bytes> trait.
  154. pub trait TypeOptionDataDeserializer {
  155. fn from_json_str(s: &str) -> Self;
  156. fn from_protobuf_bytes(bytes: Bytes) -> Self;
  157. }
  158. #[derive(Clone, Default, Deserialize, Serialize)]
  159. pub struct BuildGridContext {
  160. pub field_revs: Vec<Arc<FieldRevision>>,
  161. pub block_metas: Vec<GridBlockMetaRevision>,
  162. pub blocks: Vec<GridBlockRevision>,
  163. // String in JSON format. It can be deserialized into [GridViewRevision]
  164. pub grid_view_revision_data: String,
  165. }
  166. impl BuildGridContext {
  167. pub fn new() -> Self {
  168. Self::default()
  169. }
  170. }
  171. impl std::convert::From<BuildGridContext> for Bytes {
  172. fn from(ctx: BuildGridContext) -> Self {
  173. let bytes = serde_json::to_vec(&ctx).unwrap_or_else(|_| vec![]);
  174. Bytes::from(bytes)
  175. }
  176. }
  177. impl std::convert::TryFrom<Bytes> for BuildGridContext {
  178. type Error = serde_json::Error;
  179. fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
  180. let ctx: BuildGridContext = serde_json::from_slice(&bytes)?;
  181. Ok(ctx)
  182. }
  183. }
  184. pub type FieldTypeRevision = u8;