rusty_cat/file_transfer_record.rs
1use std::sync::Arc;
2
3use crate::direction::Direction;
4use crate::ids::TaskId;
5use crate::transfer_status::TransferStatus;
6
7/// Immutable progress/state record emitted by transfer callbacks.
8///
9/// This snapshot is safe to clone and pass across threads. `file_sign` and
10/// `file_name` are backed by `Arc<str>` so per-event fan-out only performs
11/// a refcount bump instead of string allocation.
12#[derive(Debug, Clone)]
13pub struct FileTransferRecord {
14 /// Unique task identifier.
15 task_id: TaskId,
16 /// File signature (upload usually MD5; download may use client-defined value).
17 file_sign: Arc<str>,
18 /// Display file name.
19 file_name: Arc<str>,
20 /// Total file size in bytes.
21 total_size: u64,
22 /// Progress ratio in range `0.0..=1.0`.
23 progress: f32,
24 /// Current transfer state.
25 status: TransferStatus,
26 /// Transfer direction.
27 direction: Direction,
28}
29
30impl FileTransferRecord {
31 /// Creates a new transfer record.
32 ///
33 /// # Range guidance
34 ///
35 /// - `total_size >= 0`
36 /// - `progress` should stay in `0.0..=1.0`
37 ///
38 /// # Examples
39 ///
40 /// ```no_run
41 /// use rusty_cat::api::{Direction, FileTransferRecord, TaskId, TransferStatus};
42 ///
43 /// # fn sample(task_id: TaskId) {
44 /// let record = FileTransferRecord::new(
45 /// task_id,
46 /// "sign".to_string(),
47 /// "file.bin".to_string(),
48 /// 1024,
49 /// 0.5,
50 /// TransferStatus::Transmission,
51 /// Direction::Download,
52 /// );
53 /// assert_eq!(record.total_size(), 1024);
54 /// # }
55 /// ```
56 pub fn new(
57 task_id: TaskId,
58 file_sign: impl Into<Arc<str>>,
59 file_name: impl Into<Arc<str>>,
60 total_size: u64,
61 progress: f32,
62 status: TransferStatus,
63 direction: Direction,
64 ) -> Self {
65 Self {
66 task_id,
67 file_sign: file_sign.into(),
68 file_name: file_name.into(),
69 total_size,
70 progress,
71 status,
72 direction,
73 }
74 }
75
76 /// Returns file signature.
77 ///
78 /// # Examples
79 ///
80 /// ```no_run
81 /// use rusty_cat::api::FileTransferRecord;
82 ///
83 /// fn read_sign(record: &FileTransferRecord) {
84 /// let _ = record.file_sign();
85 /// }
86 /// ```
87 pub fn file_sign(&self) -> &str {
88 &self.file_sign
89 }
90
91 /// Returns display file name.
92 ///
93 /// # Examples
94 ///
95 /// ```no_run
96 /// use rusty_cat::api::FileTransferRecord;
97 ///
98 /// fn read_name(record: &FileTransferRecord) {
99 /// let _ = record.file_name();
100 /// }
101 /// ```
102 pub fn file_name(&self) -> &str {
103 &self.file_name
104 }
105
106 /// Returns total file size in bytes.
107 ///
108 /// # Examples
109 ///
110 /// ```no_run
111 /// use rusty_cat::api::FileTransferRecord;
112 ///
113 /// fn read_size(record: &FileTransferRecord) {
114 /// let _ = record.total_size();
115 /// }
116 /// ```
117 pub fn total_size(&self) -> u64 {
118 self.total_size
119 }
120
121 /// Returns progress ratio in range `0.0..=1.0`.
122 ///
123 /// # Examples
124 ///
125 /// ```no_run
126 /// use rusty_cat::api::FileTransferRecord;
127 ///
128 /// fn read_progress(record: &FileTransferRecord) {
129 /// let _ = record.progress();
130 /// }
131 /// ```
132 pub fn progress(&self) -> f32 {
133 self.progress
134 }
135
136 /// Returns current transfer status.
137 ///
138 /// # Examples
139 ///
140 /// ```no_run
141 /// use rusty_cat::api::FileTransferRecord;
142 ///
143 /// fn read_status(record: &FileTransferRecord) {
144 /// let _ = record.status();
145 /// }
146 /// ```
147 pub fn status(&self) -> &TransferStatus {
148 &self.status
149 }
150
151 /// Returns transfer direction.
152 ///
153 /// # Examples
154 ///
155 /// ```no_run
156 /// use rusty_cat::api::FileTransferRecord;
157 ///
158 /// fn read_direction(record: &FileTransferRecord) {
159 /// let _ = record.direction();
160 /// }
161 /// ```
162 pub fn direction(&self) -> Direction {
163 self.direction
164 }
165
166 /// Returns task ID.
167 ///
168 /// # Examples
169 ///
170 /// ```no_run
171 /// use rusty_cat::api::FileTransferRecord;
172 ///
173 /// fn read_task_id(record: &FileTransferRecord) {
174 /// let _ = record.task_id();
175 /// }
176 /// ```
177 pub fn task_id(&self) -> TaskId {
178 self.task_id
179 }
180}