1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Note {
6 pub id: i64,
7 pub title: String,
8 pub body: String,
9 pub tags: Vec<String>,
10 #[serde(default)]
12 pub references: Vec<String>,
13 pub updated_at: String,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct NoteSummary {
19 pub id: i64,
20 pub title: String,
21 pub body_preview: String,
22 pub tags: Vec<String>,
23 pub updated_at: String,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct TagCount {
29 pub name: String,
30 pub count: i64,
31}
32
33#[derive(Debug, Default, Clone)]
35pub struct NoteQuery {
36 pub tags: Option<Vec<String>>,
37 pub from: Option<String>,
38 pub to: Option<String>,
39 pub limit: Option<i64>,
40}
41
42#[derive(Debug, Clone)]
44pub struct CreateNote {
45 pub title: String,
46 pub body: String,
47 pub tags: Vec<String>,
48 pub references: Vec<String>,
50}
51
52#[derive(Debug, Default, Clone)]
54pub struct UpdateNote {
55 pub title: Option<String>,
56 pub body: Option<String>,
57 pub tags: Option<Vec<String>>,
58 pub references: Option<Vec<String>>,
60}
61
62impl Note {
63 pub fn to_summary(&self, max_len: usize) -> NoteSummary {
65 let normalized: String = self
67 .body
68 .chars()
69 .map(|c| if c == '\n' || c == '\r' { ' ' } else { c })
70 .collect();
71 let trimmed = normalized.trim();
72
73 let body_preview = if trimmed.len() > max_len {
74 format!("{}...", &trimmed[..max_len])
75 } else if trimmed.len() < self.body.trim().len() {
76 trimmed.to_string()
78 } else {
79 trimmed.to_string()
80 };
81
82 NoteSummary {
83 id: self.id,
84 title: self.title.clone(),
85 body_preview,
86 tags: self.tags.clone(),
87 updated_at: self.updated_at.clone(),
88 }
89 }
90}