Skip to main content

sendcipher_core/crypto/
metadata.rs

1/* Created on 2025.11.28 */
2/* Copyright (c) 2025-2026 Youcef Lemsafer */
3/* SPDX-License-Identifier: MIT */
4/// @file metadata.rs
5/// Defines the metadata to be written encrypted in the blobs
6use serde::{Deserialize, Serialize};
7use std::io::Cursor;
8
9#[repr(u8)]
10#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
11pub enum FileType {
12    Manifest = 1,
13    Chunk = 2,
14}
15
16#[repr(u8)]
17#[derive(Serialize, Deserialize)]
18pub enum CompressionType {
19    NopCompression = 1, // identity
20    Zstd,
21    Lzma2,
22    Bz2,
23    Zlib,
24}
25
26#[derive(Serialize, Deserialize)]
27pub struct CompressionInfo {
28    pub version: u16,
29    pub compression_type: CompressionType,
30    pub compression_level: u16,
31    pub raw_compression_parameters: Vec<u8>,
32}
33
34impl CompressionInfo {
35    const CURRENT_VERSION: u16 = 1;
36
37    pub fn new(compression_type: CompressionType, compression_level: u16) -> Self {
38        CompressionInfo {
39            version: CompressionInfo::CURRENT_VERSION,
40            compression_type: compression_type,
41            compression_level: compression_level,
42            raw_compression_parameters: vec![],
43        }
44    }
45}
46
47#[derive(Serialize, Deserialize)]
48pub struct Metadata {
49    pub version: u16,
50    pub file_type: FileType,
51    pub file_name: String,
52    pub file_size: u64,
53    pub padding_size: u32,
54    pub mfp: Option<Vec<u8>>,
55    pub compression_info: CompressionInfo,
56}
57
58impl Metadata {
59    const CURRENT_VERSION: u16 = 1;
60
61    pub fn new(
62        file_type: FileType,
63        file_name: &str,
64        file_size: u64,
65        padding_size: u32,
66        mfp: Option<Vec<u8>>,
67    ) -> Self {
68        Self {
69            version: Metadata::CURRENT_VERSION,
70            file_type,
71            file_name: file_name.to_string(),
72            file_size,
73            padding_size,
74            mfp,
75            compression_info: CompressionInfo::new(CompressionType::NopCompression, 0),
76        }
77    }
78}
79
80impl Metadata {
81    pub fn version(&self) -> u16 {
82        self.version
83    }
84
85    pub fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
86        bincode::serialize(self).map_err(|e| crate::error::Error::BincodeError(e.to_string()))
87    }
88
89    pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::error::Error> {
90        bincode::deserialize(bytes).map_err(|e| crate::error::Error::BincodeError(e.to_string()))
91    }
92
93    pub fn from_bytes_ex(bytes: &[u8]) -> Result<(Self, usize), crate::error::Error> {
94        let mut cursor = Cursor::new(bytes);
95        let metadata: Metadata = bincode::deserialize_from(&mut cursor)
96            .map_err(|e| crate::error::Error::BincodeError(e.to_string()))?;
97        let metadata_size = cursor.position() as usize;
98        Ok((metadata, metadata_size))
99    }
100}