use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use solana_program::{
account_info::AccountInfo, clock::UnixTimestamp, program_error::ProgramError, pubkey::Pubkey,
};
use spl_governance_tools::account::{assert_is_valid_account_of_type, AccountMaxSize};
#[repr(C)]
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
pub enum GovernanceChatAccountType {
Uninitialized,
ChatMessage,
}
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
pub enum MessageBody {
Text(String),
Reaction(String),
}
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
pub struct ChatMessage {
pub account_type: GovernanceChatAccountType,
pub proposal: Pubkey,
pub author: Pubkey,
pub posted_at: UnixTimestamp,
pub reply_to: Option<Pubkey>,
pub body: MessageBody,
}
impl AccountMaxSize for ChatMessage {
fn get_max_size(&self) -> Option<usize> {
let body_size = match &self.body {
MessageBody::Text(body) => body.len(),
MessageBody::Reaction(body) => body.len(),
};
Some(body_size + 111)
}
}
pub fn assert_is_valid_chat_message(
program_id: &Pubkey,
chat_message_info: &AccountInfo,
) -> Result<(), ProgramError> {
assert_is_valid_account_of_type(
program_id,
chat_message_info,
GovernanceChatAccountType::ChatMessage,
)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_max_size() {
let message = ChatMessage {
account_type: GovernanceChatAccountType::ChatMessage,
proposal: Pubkey::new_unique(),
author: Pubkey::new_unique(),
posted_at: 10,
reply_to: Some(Pubkey::new_unique()),
body: MessageBody::Text("message".to_string()),
};
let size = message.try_to_vec().unwrap().len();
assert_eq!(message.get_max_size(), Some(size));
}
}