]>
Commit | Line | Data |
---|---|---|
c1c2c8f6 DM |
1 | use anyhow::{bail, Error}; |
2 | ||
3 | use proxmox::api::{ | |
4 | schema::{ | |
5 | Schema, | |
6 | StringSchema, | |
7 | ApiStringFormat, | |
8 | parse_simple_value, | |
9 | }, | |
10 | }; | |
11 | ||
12 | use crate::api2::types::{ | |
13 | PROXMOX_SAFE_ID_FORMAT, | |
14 | CHANGER_NAME_SCHEMA, | |
15 | }; | |
16 | ||
17 | pub const VAULT_NAME_SCHEMA: Schema = StringSchema::new("Vault name.") | |
18 | .format(&PROXMOX_SAFE_ID_FORMAT) | |
19 | .min_length(3) | |
20 | .max_length(32) | |
21 | .schema(); | |
22 | ||
23 | #[derive(Debug, PartialEq, Clone)] | |
24 | /// Media location | |
25 | pub enum MediaLocation { | |
26 | /// Ready for use (inside tape library) | |
27 | Online(String), | |
28 | /// Local available, but need to be mounted (insert into tape | |
29 | /// drive) | |
30 | Offline, | |
31 | /// Media is inside a Vault | |
32 | Vault(String), | |
33 | } | |
34 | ||
35 | proxmox::forward_deserialize_to_from_str!(MediaLocation); | |
36 | proxmox::forward_serialize_to_display!(MediaLocation); | |
37 | ||
a37c8d24 WB |
38 | impl proxmox::api::schema::ApiType for MediaLocation { |
39 | const API_SCHEMA: Schema = StringSchema::new( | |
c1c2c8f6 DM |
40 | "Media location (e.g. 'offline', 'online-<changer_name>', 'vault-<vault_name>')") |
41 | .format(&ApiStringFormat::VerifyFn(|text| { | |
42 | let location: MediaLocation = text.parse()?; | |
43 | match location { | |
44 | MediaLocation::Online(ref changer) => { | |
45 | parse_simple_value(changer, &CHANGER_NAME_SCHEMA)?; | |
46 | } | |
47 | MediaLocation::Vault(ref vault) => { | |
48 | parse_simple_value(vault, &VAULT_NAME_SCHEMA)?; | |
49 | } | |
50 | MediaLocation::Offline => { /* OK */} | |
51 | } | |
52 | Ok(()) | |
53 | })) | |
54 | .schema(); | |
55 | } | |
56 | ||
57 | ||
58 | impl std::fmt::Display for MediaLocation { | |
59 | ||
60 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
61 | match self { | |
62 | MediaLocation::Offline => { | |
63 | write!(f, "offline") | |
64 | } | |
65 | MediaLocation::Online(changer) => { | |
66 | write!(f, "online-{}", changer) | |
67 | } | |
68 | MediaLocation::Vault(vault) => { | |
69 | write!(f, "vault-{}", vault) | |
70 | } | |
71 | } | |
72 | } | |
73 | } | |
74 | ||
75 | impl std::str::FromStr for MediaLocation { | |
76 | type Err = Error; | |
77 | ||
78 | fn from_str(s: &str) -> Result<Self, Self::Err> { | |
79 | if s == "offline" { | |
80 | return Ok(MediaLocation::Offline); | |
81 | } | |
82 | if let Some(changer) = s.strip_prefix("online-") { | |
83 | return Ok(MediaLocation::Online(changer.to_string())); | |
84 | } | |
85 | if let Some(vault) = s.strip_prefix("vault-") { | |
7c9fb570 | 86 | return Ok(MediaLocation::Vault(vault.to_string())); |
c1c2c8f6 DM |
87 | } |
88 | ||
89 | bail!("MediaLocation parse error"); | |
90 | } | |
91 | } |