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}