azure_storage/
copy_progress.rs

1use azure_core::error::{Error, ErrorKind, ResultExt};
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::{fmt, str::FromStr};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct CopyProgress {
8    pub bytes_copied: u64,
9    pub bytes_total: u64,
10}
11
12impl fmt::Display for CopyProgress {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        write!(f, "{}/{}", self.bytes_copied, self.bytes_total)
15    }
16}
17
18impl FromStr for CopyProgress {
19    type Err = Error;
20
21    fn from_str(s: &str) -> azure_core::Result<Self> {
22        let tokens = s.split('/').collect::<Vec<&str>>();
23        if tokens.len() < 2 {
24            return Err(Error::with_message(ErrorKind::DataConversion, || {
25                format!("copy progress has insufficient tokens: {s}")
26            }));
27        }
28
29        Ok(Self {
30            bytes_copied: tokens[0]
31                .parse()
32                .with_context(ErrorKind::DataConversion, || {
33                    format!("failed to parse bytes_copied from copy progress: {s}")
34                })?,
35            bytes_total: tokens[1]
36                .parse()
37                .with_context(ErrorKind::DataConversion, || {
38                    format!("failed to parse bytes_total from copy progress: {s}")
39                })?,
40        })
41    }
42}
43
44impl Serialize for CopyProgress {
45    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
46    where
47        S: Serializer,
48    {
49        serializer.serialize_str(&self.to_string())
50    }
51}
52
53impl<'de> Deserialize<'de> for CopyProgress {
54    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
55    where
56        D: Deserializer<'de>,
57    {
58        let s = String::deserialize(deserializer)?;
59
60        s.parse()
61            .map_err(|_| serde::de::Error::custom("Failed to deserialize CopyProgress"))
62    }
63}