85 lines
2.3 KiB
Rust
85 lines
2.3 KiB
Rust
//! Persisted custom chat draft model.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use thiserror::Error;
|
|
|
|
use crate::ids::{LayoutId, NodeId, ProjectId};
|
|
|
|
/// Maximum draft text size persisted by IdeA.
|
|
pub const CHAT_DRAFT_MAX_BYTES: usize = 100 * 1024;
|
|
|
|
/// Stable scope for one custom chat draft.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ChatDraftKey {
|
|
/// Project owning the layout.
|
|
pub project_id: ProjectId,
|
|
/// Named layout containing the chat cell.
|
|
pub layout_id: LayoutId,
|
|
/// Layout node hosting the chat cell.
|
|
pub node_id: NodeId,
|
|
}
|
|
|
|
impl ChatDraftKey {
|
|
/// Builds a draft key.
|
|
#[must_use]
|
|
pub const fn new(project_id: ProjectId, layout_id: LayoutId, node_id: NodeId) -> Self {
|
|
Self {
|
|
project_id,
|
|
layout_id,
|
|
node_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Durable text draft for one custom chat composer.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ChatDraft {
|
|
/// Stable draft scope.
|
|
pub key: ChatDraftKey,
|
|
/// Draft text. Attachments are deliberately excluded.
|
|
pub text: String,
|
|
/// Last update time, epoch milliseconds.
|
|
pub updated_at_ms: u64,
|
|
}
|
|
|
|
impl ChatDraft {
|
|
/// Builds validated draft metadata.
|
|
///
|
|
/// # Errors
|
|
/// Returns [`ChatDraftError::TooLarge`] when `text` exceeds the maximum
|
|
/// persisted draft size.
|
|
pub fn new(
|
|
key: ChatDraftKey,
|
|
text: impl Into<String>,
|
|
updated_at_ms: u64,
|
|
) -> Result<Self, ChatDraftError> {
|
|
let text = text.into();
|
|
if text.len() > CHAT_DRAFT_MAX_BYTES {
|
|
return Err(ChatDraftError::TooLarge {
|
|
max: CHAT_DRAFT_MAX_BYTES,
|
|
actual: text.len(),
|
|
});
|
|
}
|
|
Ok(Self {
|
|
key,
|
|
text,
|
|
updated_at_ms,
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Chat draft validation errors.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
|
pub enum ChatDraftError {
|
|
/// Draft content exceeds the persisted size limit.
|
|
#[error("chat draft exceeds {max} bytes: {actual}")]
|
|
TooLarge {
|
|
/// Maximum allowed bytes.
|
|
max: usize,
|
|
/// Actual text bytes.
|
|
actual: usize,
|
|
},
|
|
}
|