kkv 1.2.1

A Peer-to-Peer Decentralized, Temporary and Anonymous Message System.
Documentation
/**************************************************************************
 *   src/message.rs  --  This file is part of kkv.                        *
 *                                                                        *
 *   Copyright (C) 2025 Mateo Lafalce                                     *
 *                                                                        *
 *   kkv is free software: you can redistribute it and/or modify          *
 *   it under the terms of the GNU General Public License as published    *
 *   by the Free Software Foundation, either version 3 of the License,    *
 *   or (at your option) any later version.                               *
 *                                                                        *
 *   kkv is distributed in the hope that it will be useful,               *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty          *
 *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              *
 *   See the GNU General Public License for more details.                 *
 *                                                                        *
 *   You should have received a copy of the GNU General Public License    *
 *   along with this program.  If not, see http://www.gnu.org/licenses/.  *
 *                                                                        *
 **************************************************************************/

use crate::types::{Body, Ed25519Pubkey, Ed25519Singature};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

/// Message struct
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Message {
    hs_pubkey: Vec<u8>,
    signature: Vec<u8>,
    body: Body,
    has_been_read: bool,
    date: u64,
}

impl Message {
    /// Max 3500 chars for the PGP message
    pub const CIPHERTEXT: usize = 3500;
    /// 1024 chars of plain text
    pub const MAX_SIZE_BODY: usize = 1024;
    /// Used to know if some message has been read (bool)
    pub const HAS_BEEN_READ: usize = 1;
    /// Store UNIX timestamp (u64)
    pub const DATE: usize = 8;

    pub fn new(
        hs_pubkey: Ed25519Pubkey,
        signature: Ed25519Singature,
        body: String,
    ) -> Result<Self, String> {
        if body.len() > Self::CIPHERTEXT {
            return Err(format!(
                "The Body size must be less or equal than {}",
                Self::MAX_SIZE_BODY
            ));
        }
        let has_been_read = false;

        let now = SystemTime::now();
        let duration_since_epoch = now
            .duration_since(UNIX_EPOCH)
            .unwrap_or(Duration::new(0, 0));
        let date: u64 = duration_since_epoch.as_secs();

        Ok(Self {
            hs_pubkey: hs_pubkey.to_vec(),
            signature: signature.to_vec(),
            body,
            has_been_read,
            date,
        })
    }

    pub fn get_hs_pubkey(&self) -> Ed25519Pubkey {
        let pubkey: [u8; 32] = self.hs_pubkey.clone().try_into().unwrap_or([0; 32]);
        pubkey
    }

    pub fn get_signature(&self) -> Ed25519Singature {
        let signature: [u8; 64] = self.signature.clone().try_into().unwrap_or([0; 64]);
        signature
    }

    pub fn get_body(&self) -> String {
        self.body.clone()
    }

    pub fn get_has_been_read(&self) -> bool {
        self.has_been_read
    }

    pub fn get_date(&self) -> u64 {
        self.date
    }

    pub fn read_message(&mut self) {
        self.has_been_read = true;
    }
}