nblm_core/models/
notebook.rs1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use super::source::NotebookSource;
6
7#[derive(Debug, Clone, Serialize, Deserialize, Default)]
8#[serde(rename_all = "camelCase")]
9pub struct Notebook {
10 pub name: Option<String>,
11 pub title: String,
12 #[serde(rename = "notebookId", skip_serializing_if = "Option::is_none")]
13 pub notebook_id: Option<String>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub emoji: Option<String>,
16 #[serde(default, skip_serializing_if = "Vec::is_empty")]
17 pub sources: Vec<NotebookSource>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub metadata: Option<NotebookMetadata>,
20 #[serde(flatten)]
21 pub extra: HashMap<String, serde_json::Value>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct NotebookRef {
27 pub notebook_id: String,
28 pub name: String,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize, Default)]
32#[serde(rename_all = "camelCase")]
33pub struct NotebookMetadata {
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub create_time: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub is_shareable: Option<bool>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub is_shared: Option<bool>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub last_viewed: Option<String>,
42 #[serde(flatten)]
43 pub extra: HashMap<String, serde_json::Value>,
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn notebook_skips_notebook_id_when_none() {
52 let notebook = Notebook {
53 name: Some("test".to_string()),
54 title: "Test Notebook".to_string(),
55 notebook_id: None,
56 emoji: None,
57 metadata: None,
58 sources: Vec::new(),
59 extra: Default::default(),
60 };
61 let json = serde_json::to_string(¬ebook).unwrap();
62 assert!(!json.contains("notebookId"));
63 }
64
65 #[test]
66 fn notebook_includes_notebook_id_when_some() {
67 let notebook = Notebook {
68 name: Some("test".to_string()),
69 title: "Test Notebook".to_string(),
70 notebook_id: Some("nb123".to_string()),
71 emoji: None,
72 metadata: None,
73 sources: Vec::new(),
74 extra: Default::default(),
75 };
76 let json = serde_json::to_string(¬ebook).unwrap();
77 assert!(json.contains("notebookId"));
78 assert!(json.contains("nb123"));
79 }
80}