meta.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. use crate::parser::NotEmptyUuid;
  2. use bytes::Bytes;
  3. use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
  4. use flowy_error_code::ErrorCode;
  5. use serde::{Deserialize, Serialize};
  6. use serde_repr::*;
  7. use std::collections::HashMap;
  8. use strum_macros::{Display, EnumCount as EnumCountMacro, EnumIter, EnumString};
  9. pub const DEFAULT_ROW_HEIGHT: i32 = 42;
  10. #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
  11. pub struct GridMeta {
  12. #[pb(index = 1)]
  13. pub grid_id: String,
  14. #[pb(index = 2)]
  15. pub fields: Vec<FieldMeta>,
  16. #[pb(index = 3)]
  17. pub blocks: Vec<GridBlockMeta>,
  18. }
  19. #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
  20. pub struct GridBlockMeta {
  21. #[pb(index = 1)]
  22. pub block_id: String,
  23. #[pb(index = 2)]
  24. pub start_row_index: i32,
  25. #[pb(index = 3)]
  26. pub row_count: i32,
  27. }
  28. impl GridBlockMeta {
  29. pub fn len(&self) -> i32 {
  30. self.row_count
  31. }
  32. pub fn is_empty(&self) -> bool {
  33. self.row_count == 0
  34. }
  35. }
  36. impl GridBlockMeta {
  37. pub fn new() -> Self {
  38. GridBlockMeta {
  39. block_id: uuid::Uuid::new_v4().to_string(),
  40. ..Default::default()
  41. }
  42. }
  43. }
  44. pub struct GridBlockMetaChangeset {
  45. pub block_id: String,
  46. pub start_row_index: Option<i32>,
  47. pub row_count: Option<i32>,
  48. }
  49. impl GridBlockMetaChangeset {
  50. pub fn from_row_count(block_id: &str, row_count: i32) -> Self {
  51. Self {
  52. block_id: block_id.to_string(),
  53. start_row_index: None,
  54. row_count: Some(row_count),
  55. }
  56. }
  57. }
  58. #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf)]
  59. pub struct GridBlockMetaData {
  60. #[pb(index = 1)]
  61. pub block_id: String,
  62. #[pb(index = 2)]
  63. pub rows: Vec<RowMeta>,
  64. }
  65. #[derive(Debug, Clone, Default, Serialize, Deserialize, ProtoBuf, Eq, PartialEq)]
  66. pub struct FieldMeta {
  67. #[pb(index = 1)]
  68. pub id: String,
  69. #[pb(index = 2)]
  70. pub name: String,
  71. #[pb(index = 3)]
  72. pub desc: String,
  73. #[pb(index = 4)]
  74. pub field_type: FieldType,
  75. #[pb(index = 5)]
  76. pub frozen: bool,
  77. #[pb(index = 6)]
  78. pub visibility: bool,
  79. #[pb(index = 7)]
  80. pub width: i32,
  81. #[pb(index = 8)]
  82. /// type_options contains key/value pairs
  83. /// key: id of the FieldType
  84. /// value: type option data string
  85. pub type_options: HashMap<String, String>,
  86. }
  87. impl FieldMeta {
  88. pub fn new(name: &str, desc: &str, field_type: FieldType) -> Self {
  89. let width = field_type.default_cell_width();
  90. Self {
  91. id: uuid::Uuid::new_v4().to_string(),
  92. name: name.to_string(),
  93. desc: desc.to_string(),
  94. field_type,
  95. frozen: false,
  96. visibility: true,
  97. width,
  98. type_options: Default::default(),
  99. }
  100. }
  101. pub fn insert_type_option_entry<T: TypeOptionDataEntry + ?Sized>(&mut self, entry: &T) {
  102. self.type_options.insert(entry.field_type().type_id(), entry.json_str());
  103. }
  104. pub fn get_type_option_entry<T: TypeOptionDataEntity>(&self, field_type: Option<FieldType>) -> Option<T> {
  105. let field_type = field_type.as_ref().unwrap_or(&self.field_type);
  106. self.type_options
  107. .get(&field_type.type_id())
  108. .map(|s| T::from_json_str(s))
  109. }
  110. pub fn insert_type_option_str(&mut self, field_type: &FieldType, json_str: String) {
  111. self.type_options.insert(field_type.type_id(), json_str);
  112. }
  113. pub fn get_type_option_str(&self, field_type: Option<FieldType>) -> Option<String> {
  114. let field_type = field_type.as_ref().unwrap_or(&self.field_type);
  115. self.type_options.get(&field_type.type_id()).map(|s| s.to_owned())
  116. }
  117. }
  118. pub trait TypeOptionDataEntry {
  119. fn field_type(&self) -> FieldType;
  120. fn json_str(&self) -> String;
  121. fn protobuf_bytes(&self) -> Bytes;
  122. }
  123. pub trait TypeOptionDataEntity {
  124. fn from_json_str(s: &str) -> Self;
  125. fn from_protobuf_bytes(bytes: Bytes) -> Self;
  126. }
  127. #[derive(Debug, Clone, Default, ProtoBuf)]
  128. pub struct FieldChangesetPayload {
  129. #[pb(index = 1)]
  130. pub field_id: String,
  131. #[pb(index = 2)]
  132. pub grid_id: String,
  133. #[pb(index = 3, one_of)]
  134. pub name: Option<String>,
  135. #[pb(index = 4, one_of)]
  136. pub desc: Option<String>,
  137. #[pb(index = 5, one_of)]
  138. pub field_type: Option<FieldType>,
  139. #[pb(index = 6, one_of)]
  140. pub frozen: Option<bool>,
  141. #[pb(index = 7, one_of)]
  142. pub visibility: Option<bool>,
  143. #[pb(index = 8, one_of)]
  144. pub width: Option<i32>,
  145. #[pb(index = 9, one_of)]
  146. pub type_option_data: Option<Vec<u8>>,
  147. }
  148. #[derive(Debug, Clone, Default)]
  149. pub struct FieldChangesetParams {
  150. pub field_id: String,
  151. pub grid_id: String,
  152. pub name: Option<String>,
  153. pub desc: Option<String>,
  154. pub field_type: Option<FieldType>,
  155. pub frozen: Option<bool>,
  156. pub visibility: Option<bool>,
  157. pub width: Option<i32>,
  158. pub type_option_data: Option<Vec<u8>>,
  159. }
  160. impl TryInto<FieldChangesetParams> for FieldChangesetPayload {
  161. type Error = ErrorCode;
  162. fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
  163. let grid_id = NotEmptyUuid::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  164. let field_id = NotEmptyUuid::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  165. if let Some(type_option_data) = self.type_option_data.as_ref() {
  166. if type_option_data.is_empty() {
  167. return Err(ErrorCode::TypeOptionDataIsEmpty);
  168. }
  169. }
  170. Ok(FieldChangesetParams {
  171. field_id: field_id.0,
  172. grid_id: grid_id.0,
  173. name: self.name,
  174. desc: self.desc,
  175. field_type: self.field_type,
  176. frozen: self.frozen,
  177. visibility: self.visibility,
  178. width: self.width,
  179. type_option_data: self.type_option_data,
  180. })
  181. }
  182. }
  183. #[derive(
  184. Debug,
  185. Clone,
  186. PartialEq,
  187. Eq,
  188. ProtoBuf_Enum,
  189. EnumCountMacro,
  190. EnumString,
  191. EnumIter,
  192. Display,
  193. Serialize_repr,
  194. Deserialize_repr,
  195. )]
  196. #[repr(u8)]
  197. pub enum FieldType {
  198. RichText = 0,
  199. Number = 1,
  200. DateTime = 2,
  201. SingleSelect = 3,
  202. MultiSelect = 4,
  203. Checkbox = 5,
  204. }
  205. impl std::default::Default for FieldType {
  206. fn default() -> Self {
  207. FieldType::RichText
  208. }
  209. }
  210. impl AsRef<FieldType> for FieldType {
  211. fn as_ref(&self) -> &FieldType {
  212. self
  213. }
  214. }
  215. impl From<&FieldType> for FieldType {
  216. fn from(field_type: &FieldType) -> Self {
  217. field_type.clone()
  218. }
  219. }
  220. impl FieldType {
  221. pub fn type_id(&self) -> String {
  222. let ty = self.clone();
  223. format!("{}", ty as u8)
  224. }
  225. pub fn default_cell_width(&self) -> i32 {
  226. match self {
  227. FieldType::DateTime => 180,
  228. _ => 150,
  229. }
  230. }
  231. }
  232. #[derive(Debug, Clone, Serialize, Deserialize, Default, ProtoBuf)]
  233. pub struct AnyData {
  234. #[pb(index = 1)]
  235. pub type_id: String,
  236. #[pb(index = 2)]
  237. pub value: Vec<u8>,
  238. }
  239. impl AnyData {
  240. pub fn from_str<F: Into<FieldType>>(field_type: F, s: &str) -> AnyData {
  241. Self::from_bytes(field_type, s.as_bytes().to_vec())
  242. }
  243. pub fn from_bytes<T: AsRef<[u8]>, F: Into<FieldType>>(field_type: F, bytes: T) -> AnyData {
  244. AnyData {
  245. type_id: field_type.into().type_id(),
  246. value: bytes.as_ref().to_vec(),
  247. }
  248. }
  249. }
  250. impl ToString for AnyData {
  251. fn to_string(&self) -> String {
  252. match String::from_utf8(self.value.clone()) {
  253. Ok(s) => s,
  254. Err(_) => "".to_owned(),
  255. }
  256. }
  257. }
  258. #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
  259. pub struct RowMeta {
  260. #[pb(index = 1)]
  261. pub id: String,
  262. #[pb(index = 2)]
  263. pub block_id: String,
  264. #[pb(index = 3)]
  265. /// cells contains key/value pairs.
  266. /// key: field id,
  267. /// value: CellMeta
  268. pub cells: HashMap<String, CellMeta>,
  269. #[pb(index = 4)]
  270. pub height: i32,
  271. #[pb(index = 5)]
  272. pub visibility: bool,
  273. }
  274. impl RowMeta {
  275. pub fn new(block_id: &str) -> Self {
  276. Self {
  277. id: uuid::Uuid::new_v4().to_string(),
  278. block_id: block_id.to_owned(),
  279. cells: Default::default(),
  280. height: DEFAULT_ROW_HEIGHT,
  281. visibility: true,
  282. }
  283. }
  284. }
  285. #[derive(Debug, Clone, Default, ProtoBuf)]
  286. pub struct RowMetaChangeset {
  287. #[pb(index = 1)]
  288. pub row_id: String,
  289. #[pb(index = 2, one_of)]
  290. pub height: Option<i32>,
  291. #[pb(index = 3, one_of)]
  292. pub visibility: Option<bool>,
  293. #[pb(index = 4)]
  294. pub cell_by_field_id: HashMap<String, CellMeta>,
  295. }
  296. #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ProtoBuf)]
  297. pub struct CellMeta {
  298. #[pb(index = 1)]
  299. pub data: String,
  300. }
  301. impl CellMeta {
  302. pub fn new(data: String) -> Self {
  303. Self { data }
  304. }
  305. }
  306. #[derive(Debug, Clone, Default, ProtoBuf)]
  307. pub struct CellMetaChangeset {
  308. #[pb(index = 1)]
  309. pub grid_id: String,
  310. #[pb(index = 2)]
  311. pub row_id: String,
  312. #[pb(index = 3)]
  313. pub field_id: String,
  314. #[pb(index = 4, one_of)]
  315. pub data: Option<String>,
  316. }
  317. impl std::convert::From<CellMetaChangeset> for RowMetaChangeset {
  318. fn from(changeset: CellMetaChangeset) -> Self {
  319. let mut cell_by_field_id = HashMap::with_capacity(1);
  320. let field_id = changeset.field_id;
  321. let cell_meta = CellMeta {
  322. data: changeset.data.unwrap_or_else(|| "".to_owned()),
  323. };
  324. cell_by_field_id.insert(field_id, cell_meta);
  325. RowMetaChangeset {
  326. row_id: changeset.row_id,
  327. height: None,
  328. visibility: None,
  329. cell_by_field_id,
  330. }
  331. }
  332. }
  333. #[derive(Clone, ProtoBuf)]
  334. pub struct BuildGridContext {
  335. #[pb(index = 1)]
  336. pub field_metas: Vec<FieldMeta>,
  337. #[pb(index = 2)]
  338. pub block_meta: GridBlockMeta,
  339. #[pb(index = 3)]
  340. pub block_meta_data: GridBlockMetaData,
  341. }
  342. impl std::default::Default for BuildGridContext {
  343. fn default() -> Self {
  344. let block_meta = GridBlockMeta::new();
  345. let block_meta_data = GridBlockMetaData {
  346. block_id: block_meta.block_id.clone(),
  347. rows: vec![],
  348. };
  349. Self {
  350. field_metas: vec![],
  351. block_meta,
  352. block_meta_data,
  353. }
  354. }
  355. }