portal_lib/protocol/
transferinfo.rs

1use crate::errors::PortalError::*;
2use serde::{Deserialize, Serialize};
3use std::error::Error;
4use std::path::{Path, PathBuf};
5
6/// Metadata about the transfer to be exchanged
7/// between peers after key derivation (encrypted)
8#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Default)]
9pub struct Metadata {
10    //pub id: u32,
11    pub filesize: u64,
12    pub filename: String,
13}
14
15/// Contains the metadata for all files that will be sent
16/// during a particular transfer
17#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Default)]
18pub struct TransferInfo {
19    /// The metadata to send to the peer. These
20    /// filenames are striped of their path information
21    pub all: Vec<Metadata>,
22
23    /// Internal state for a sender to locate files
24    #[serde(skip)]
25    pub localpaths: Vec<PathBuf>,
26}
27
28/// Builder for TransferInfo
29pub struct TransferInfoBuilder(TransferInfo);
30
31impl TransferInfo {
32    /// Owned TransferInfo
33    ///
34    /// ```
35    /// use std::path::PathBuf;
36    /// use std::error::Error;
37    /// use portal_lib::TransferInfo;
38    ///
39    /// fn create_info(files: Vec<PathBuf>) -> Result<TransferInfo, Box<dyn Error>> {
40    ///     let mut info = TransferInfo::empty();
41    ///
42    ///     for file in files {
43    ///         info.add_file(file.as_path())?;
44    ///     }
45    ///
46    ///     Ok(info)
47    /// }
48    /// ```
49    pub fn empty() -> TransferInfo {
50        TransferInfo {
51            all: Vec::new(),
52            localpaths: Vec::new(),
53        }
54    }
55
56    /// Add a file to this transfer
57    pub fn add_file<'a>(&'a mut self, path: &Path) -> Result<&'a mut TransferInfo, Box<dyn Error>> {
58        self.localpaths.push(path.to_path_buf());
59        self.all.push(Metadata {
60            filesize: path.metadata()?.len(),
61            filename: path
62                .file_name()
63                .ok_or(BadFileName)?
64                .to_str()
65                .ok_or(BadFileName)?
66                .to_string(),
67        });
68        Ok(self)
69    }
70}
71
72impl Default for TransferInfoBuilder {
73    fn default() -> Self {
74        Self::new()
75    }
76}
77
78impl TransferInfoBuilder {
79    /// Builder pattern for TransferInfo
80    ///
81    /// ```
82    /// use std::path::Path;
83    /// use std::error::Error;
84    /// use portal_lib::TransferInfoBuilder;
85    ///
86    /// fn some_method() -> Result<(), Box<dyn Error>> {
87    ///     // Use the builder to create a TransferInfo object
88    ///     let mut info = TransferInfoBuilder::new()
89    ///         .add_file(Path::new("/etc/passwd"))?
90    ///         .finalize();
91    ///
92    ///     // ... Pass it to methods that require it ...
93    ///     Ok(())
94    /// }
95    /// ```
96    pub fn new() -> TransferInfoBuilder {
97        Self(TransferInfo::empty())
98    }
99
100    pub fn add_file(mut self, path: &Path) -> Result<TransferInfoBuilder, Box<dyn Error>> {
101        let _ = self.0.add_file(path)?;
102        Ok(self)
103    }
104
105    /// Finalize the builder into a TransferInfo object
106    pub fn finalize(self) -> TransferInfo {
107        self.0
108    }
109}