]> git.proxmox.com Git - proxmox-backup.git/blob - src/api2/types/tape/media_location.rs
use ApiType trait
[proxmox-backup.git] / src / api2 / types / tape / media_location.rs
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
38 impl proxmox::api::schema::ApiType for MediaLocation {
39 const API_SCHEMA: Schema = StringSchema::new(
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-") {
86 return Ok(MediaLocation::Vault(vault.to_string()));
87 }
88
89 bail!("MediaLocation parse error");
90 }
91 }