Skip to main content

sendcipher_core/crypto/
manifest.rs

1/* Created on 2025-10-24 */
2/* Copyright (c) 2025-2026 Youcef Lemsafer */
3/* SPDX-License-Identifier: MIT */
4
5use digest::typenum::Length;
6
7use crate::crypto::random;
8use crate::crypto::checksum::*;
9
10#[derive(Clone, serde::Serialize, serde::Deserialize, Default)]
11pub struct ChunkDescriptor {
12    id: String,
13    checksum: Vec<u8>,
14    offset: u64,
15    length: u64
16}
17
18#[derive(Clone, serde::Serialize, serde::Deserialize, Default)]
19pub struct Manifest {
20    version: u32,
21    file_name: String,
22    file_size: u64,
23    /// Manifest fingerprint
24    mfp: Vec<u8>,
25    /// Checksum algorithm to use for computing chunk checksums
26    checksum_algorithm: ChecksumAlgorithm,
27    /// Chunks information
28    chunks: Vec<ChunkDescriptor>,
29}
30
31impl ChunkDescriptor {
32    pub fn new(id: String, checksum: Vec<u8>, offset: u64, length: u64) -> Self {
33        Self {id, checksum, offset, length}
34    }
35    pub fn id(&self) -> &String {
36        &self.id
37    }
38    pub fn set_id(&mut self, chunk_id: String) {
39        self.id = chunk_id;
40    }
41    pub fn checksum(&self) -> &Vec<u8> {
42        &self.checksum
43    }
44    pub fn offset(&self) -> u64 {
45        self.offset
46    }
47    pub fn length(&self) -> u64 {
48        self.length
49    }
50}
51
52impl Manifest {
53    const CURRENT_VERSION: u32 = 1;
54    const MFP_LENGTH: usize = 48;
55
56    pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::error::Error> {
57        return bincode::deserialize_from(bytes)
58            .map_err(|e| crate::error::Error::DeserializationError(e.to_string()));
59    }
60
61    pub fn to_bytes(&self) -> Result<Vec<u8>, crate::error::Error> {
62        return bincode::serialize(self)
63            .map_err(|e| crate::error::Error::SerializationError(e.to_string()));
64    }
65
66    pub fn new(file_name: String, file_size: u64) -> Result<Self, crate::error::Error> {
67        Ok(Self {
68            version: Manifest::CURRENT_VERSION,
69            file_name: file_name,
70            file_size: file_size,
71            mfp: random::get_rand_bytes(Manifest::MFP_LENGTH)?,
72            checksum_algorithm: ChecksumAlgorithm::Blake3,
73            chunks: vec![],
74        })
75    }
76
77    pub fn file_name(&self) -> &String {
78        &self.file_name
79    }
80
81    pub fn file_size(&self) -> u64 {
82        self.file_size
83    }
84
85    pub fn set_file_size(&mut self, file_size: u64) -> &mut Self {
86        self.file_size = file_size;
87        self
88    }
89
90    pub fn chunks_count(&self) -> usize {
91        self.chunks.len()
92    }
93
94    pub fn chunks(&self) -> &Vec<ChunkDescriptor> {
95        &self.chunks
96    }
97
98    pub fn chunks_mut(&mut self) -> &mut Vec<ChunkDescriptor> {
99        &mut self.chunks
100    }
101
102    pub fn mfp(&self) -> &Vec<u8> {
103        &self.mfp
104    }
105
106    pub fn checksum_algorithm(&self) -> ChecksumAlgorithm {
107        self.checksum_algorithm.clone()
108    }
109}