1use crate::aux;
4use anyhow::{bail, Result};
5use clap::ValueEnum;
6use serde::{Deserialize, Serialize};
7use std::{collections::HashMap, fmt::Display, path::Path};
8
9#[derive(Serialize, Deserialize, Debug, Clone, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
11pub enum DriveType {
12 #[serde(rename = "1541")]
13 CBM1541,
14 #[serde(rename = "1571")]
15 CBM1571,
16 #[serde(rename = "1581")]
17 CBM1581,
18 #[serde(rename = "DOS emulation")]
19 DOS,
20}
21
22impl Display for DriveType {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 let s = match self {
25 Self::CBM1541 => "1541",
26 Self::CBM1571 => "1571",
27 Self::CBM1581 => "1581",
28 Self::DOS => "DOS emulation",
29 };
30 write!(f, "{s}")
31 }
32}
33
34#[derive(Serialize, Deserialize, Debug, Clone, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
36pub enum DiskImageType {
37 #[clap(name = "d64")]
38 D64,
39 #[clap(name = "g64")]
40 G64,
41 #[clap(name = "d71")]
42 D71,
43 #[clap(name = "g71")]
44 G71,
45 #[clap(name = "d81")]
46 D81,
47}
48
49impl DiskImageType {
50 pub fn from_file_name<T: AsRef<Path>>(path: T) -> Result<Self> {
52 let ext = aux::get_extension(path).unwrap_or_default();
53 Ok(match ext.as_str() {
54 "d64" => Self::D64,
55 "d71" => Self::D71,
56 "d81" => Self::D81,
57 "g64" => Self::G64,
58 "g71" => Self::G71,
59 _ => bail!("File extension must be one of: d64, g64, d71, g71, d81"),
60 })
61 }
62}
63
64impl Display for DiskImageType {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 let s = match self {
67 Self::D64 => "d64",
68 Self::G64 => "g64",
69 Self::D71 => "d71",
70 Self::G71 => "g71",
71 Self::D81 => "d81",
72 };
73 write!(f, "{s}")
74 }
75}
76
77#[derive(Serialize, Deserialize, Debug, Clone, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
79pub enum MountMode {
80 #[clap(name = "rw")]
82 ReadWrite,
83 #[clap(name = "ro")]
85 ReadOnly,
86 #[clap(name = "ul")]
88 Unlinked,
89}
90
91impl TryFrom<&str> for MountMode {
92 type Error = String;
93 fn try_from(s: &str) -> Result<Self, Self::Error> {
94 use MountMode::*;
95 match s {
96 "readwrite" => Ok(ReadWrite),
97 "readonly" => Ok(ReadOnly),
98 "unlinked" => Ok(Unlinked),
99 _ => Err(format!("Unknown mount mode: {s}")),
100 }
101 }
102}
103
104impl Display for MountMode {
105 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106 use MountMode::*;
107 let s = match self {
108 ReadWrite => "readwrite",
109 ReadOnly => "readonly",
110 Unlinked => "unlinked",
111 };
112 write!(f, "{s}")
113 }
114}
115
116#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
118pub struct Drive {
119 pub bus_id: u8,
121 pub enabled: bool,
123 #[serde(rename = "type")]
125 pub drive_type: Option<DriveType>,
126 pub last_error: Option<String>,
128 pub rom: Option<String>,
130 pub image_file: Option<String>,
132 pub image_path: Option<String>,
134}
135
136#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
138pub struct DriveList {
139 pub drives: Vec<HashMap<String, Drive>>,
141}