use crate::aux;
use anyhow::{bail, Result};
use clap::ValueEnum;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt::Display, path::Path};
#[derive(Serialize, Deserialize, Debug, Clone, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
pub enum DriveType {
#[serde(rename = "1541")]
CBM1541,
#[serde(rename = "1571")]
CBM1571,
#[serde(rename = "1581")]
CBM1581,
#[serde(rename = "DOS emulation")]
DOS,
}
impl Display for DriveType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::CBM1541 => "1541",
Self::CBM1571 => "1571",
Self::CBM1581 => "1581",
Self::DOS => "DOS emulation",
};
write!(f, "{s}")
}
}
#[derive(Serialize, Deserialize, Debug, Clone, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
pub enum DiskImageType {
#[clap(name = "d64")]
D64,
#[clap(name = "g64")]
G64,
#[clap(name = "d71")]
D71,
#[clap(name = "g71")]
G71,
#[clap(name = "d81")]
D81,
}
impl DiskImageType {
pub fn from_file_name<T: AsRef<Path>>(path: T) -> Result<Self> {
let ext = aux::get_extension(path).unwrap_or_default();
Ok(match ext.as_str() {
"d64" => Self::D64,
"d71" => Self::D71,
"d81" => Self::D81,
"g64" => Self::G64,
"g71" => Self::G71,
_ => bail!("File extension must be one of: d64, g64, d71, g71, d81"),
})
}
}
impl Display for DiskImageType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::D64 => "d64",
Self::G64 => "g64",
Self::D71 => "d71",
Self::G71 => "g71",
Self::D81 => "d81",
};
write!(f, "{s}")
}
}
#[derive(Serialize, Deserialize, Debug, Clone, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
pub enum MountMode {
#[clap(name = "rw")]
ReadWrite,
#[clap(name = "ro")]
ReadOnly,
#[clap(name = "ul")]
Unlinked,
}
impl TryFrom<&str> for MountMode {
type Error = String;
fn try_from(s: &str) -> Result<Self, Self::Error> {
use MountMode::*;
match s {
"readwrite" => Ok(ReadWrite),
"readonly" => Ok(ReadOnly),
"unlinked" => Ok(Unlinked),
_ => Err(format!("Unknown mount mode: {s}")),
}
}
}
impl Display for MountMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use MountMode::*;
let s = match self {
ReadWrite => "readwrite",
ReadOnly => "readonly",
Unlinked => "unlinked",
};
write!(f, "{s}")
}
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct Drive {
pub bus_id: u8,
pub enabled: bool,
#[serde(rename = "type")]
pub drive_type: Option<DriveType>,
pub last_error: Option<String>,
pub rom: Option<String>,
pub image_file: Option<String>,
pub image_path: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)]
pub struct DriveList {
pub drives: Vec<HashMap<String, Drive>>,
}