statehub_api/v0/volume/
impls.rs

1//
2// Copyright (c) 2021 RepliXio Ltd. All rights reserved.
3// Use is subject to license terms.
4//
5
6use std::fmt;
7use std::str;
8
9use thiserror::Error;
10
11use super::*;
12
13impl From<String> for VolumeName {
14    fn from(name: String) -> Self {
15        Self(name)
16    }
17}
18
19impl fmt::Display for VolumeName {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        self.0.fmt(f)
22    }
23}
24
25impl str::FromStr for VolumeName {
26    type Err = String;
27
28    fn from_str(text: &str) -> Result<Self, Self::Err> {
29        Ok(text.to_string().into())
30    }
31}
32
33impl AsRef<str> for VolumeName {
34    fn as_ref(&self) -> &str {
35        self.0.as_ref()
36    }
37}
38
39impl PartialEq<&str> for VolumeName {
40    fn eq(&self, other: &&str) -> bool {
41        self.0.eq(other)
42    }
43}
44
45#[derive(Debug, Error)]
46#[error(r#"Invalid file system type "{file_system}"#)]
47pub struct InvalidVolumeFileSystem {
48    file_system: String,
49}
50
51impl InvalidVolumeFileSystem {
52    pub(crate) fn new(fs: &str) -> Self {
53        let file_system = fs.to_string();
54        Self { file_system }
55    }
56}
57
58impl VolumeFileSystem {
59    fn as_str(&self) -> &'static str {
60        match self {
61            Self::Ext => "ext",
62            Self::Ext2 => "ext2",
63            Self::Ext3 => "ext3",
64            Self::Ext4 => "ext4",
65            Self::Jfs => "jfs",
66            Self::Swap => "swap",
67            Self::Fat => "fat",
68            Self::Fat32 => "fat32",
69        }
70    }
71}
72
73impl Default for VolumeFileSystem {
74    fn default() -> Self {
75        Self::Ext4
76    }
77}
78
79impl str::FromStr for VolumeFileSystem {
80    type Err = InvalidVolumeFileSystem;
81
82    fn from_str(fs: &str) -> Result<Self, Self::Err> {
83        match fs {
84            "ext" => Ok(Self::Ext),
85            "ext2" => Ok(Self::Ext2),
86            "ext3" => Ok(Self::Ext3),
87            "ext4" => Ok(Self::Ext4),
88            "jfs" => Ok(Self::Jfs),
89            "swap" => Ok(Self::Swap),
90            "fat" => Ok(Self::Fat),
91            "fat32" => Ok(Self::Fat32),
92            other => Err(InvalidVolumeFileSystem::new(other)),
93        }
94    }
95}
96
97impl fmt::Display for VolumeFileSystem {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        let text = self.as_str();
100        text.fmt(f)
101    }
102}
103
104impl VolumeStatus {
105    fn as_str(&self) -> &'static str {
106        match self {
107            Self::Ok => "ok",
108            Self::Degraded => "degraded",
109            Self::Error => "error",
110            Self::Syncing => "syncing",
111            Self::Pending => "pending",
112        }
113    }
114}
115
116impl fmt::Display for VolumeStatus {
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118        self.as_str().fmt(f)
119    }
120}
121
122#[derive(Debug, Error)]
123#[error(r#"Invalid volume status "{status}"#)]
124pub struct InvalidVolumeStatus {
125    pub status: String,
126}
127
128impl InvalidVolumeStatus {
129    pub(crate) fn new(status: &str) -> Self {
130        let status = status.to_string();
131        Self { status }
132    }
133}
134
135impl str::FromStr for VolumeStatus {
136    type Err = InvalidVolumeStatus;
137
138    fn from_str(s: &str) -> Result<Self, Self::Err> {
139        match s {
140            "ok" => Ok(Self::Ok),
141            "degraded" => Ok(Self::Degraded),
142            "error" => Ok(Self::Error),
143            "syncing" => Ok(Self::Syncing),
144            "pending" => Ok(Self::Pending),
145            other => Err(InvalidVolumeStatus::new(other)),
146        }
147    }
148}
149
150impl LocationVolumeStatus {
151    pub fn is_deleting(&self) -> bool {
152        self.value.is_deleting()
153    }
154}
155
156impl Volume {
157    pub fn is_deleting(&self) -> bool {
158        self.locations
159            .iter()
160            .any(|location| location.status.is_deleting())
161    }
162
163    pub fn progress(&self) -> Option<(&LocationVolumeStatus, &StateLocationVolumeProgress)> {
164        self.locations.iter().find_map(|location| {
165            location
166                .progress
167                .as_ref()
168                .map(|progress| (&location.status, progress))
169        })
170    }
171}