Skip to main content

veta_core/
note.rs

1use serde::{Deserialize, Serialize};
2
3/// A full note with all fields.
4#[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    /// References to external resources (source code paths, URLs, documentation links, etc.)
11    #[serde(default)]
12    pub references: Vec<String>,
13    pub updated_at: String,
14}
15
16/// A summary of a note for listing (truncated body).
17#[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/// Tag with note count.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct TagCount {
29    pub name: String,
30    pub count: i64,
31}
32
33/// Query parameters for listing notes.
34#[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/// Parameters for creating a new note.
43#[derive(Debug, Clone)]
44pub struct CreateNote {
45    pub title: String,
46    pub body: String,
47    pub tags: Vec<String>,
48    /// References to external resources (source code paths, URLs, documentation links, etc.)
49    pub references: Vec<String>,
50}
51
52/// Parameters for updating an existing note.
53#[derive(Debug, Default, Clone)]
54pub struct UpdateNote {
55    pub title: Option<String>,
56    pub body: Option<String>,
57    pub tags: Option<Vec<String>>,
58    /// References to external resources (source code paths, URLs, documentation links, etc.)
59    pub references: Option<Vec<String>>,
60}
61
62impl Note {
63    /// Convert to summary with truncated body preview.
64    pub fn to_summary(&self, max_len: usize) -> NoteSummary {
65        // Convert newlines to spaces and take first max_len characters
66        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            // Content was truncated due to newline normalization showing less
77            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}