Skip to content

Commit

Permalink
feat: Start work on quickemu rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
lj3954 committed Dec 20, 2024
1 parent 3b658f0 commit 0061944
Show file tree
Hide file tree
Showing 12 changed files with 817 additions and 10 deletions.
90 changes: 81 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
license = "GPL-3.0"

[workspace]
members = ["quickemu", "quickget/cli", "quickget/core"]
members = ["quickemu", "quickget/cli", "quickget/core", "quickemu/core"]

resolver = "2"

Expand Down
5 changes: 5 additions & 0 deletions quickemu/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
[package]
name = "quickemu_core"
edition = "2021"
version = "1.0.0"
license.workspace = true

[dependencies]
anyhow = "1.0.81"
clap = { version = "4.5.4", features = ["derive"] }
clap-verbosity-flag = "2.2.0"
derive_more = { version = "1.0.0", features = ["display", "as_ref"] }
dirs = "5.0.1"
display-info = "0.5.1"
env_logger = "0.11.3"
Expand All @@ -19,6 +21,9 @@ serde = { version = "1.0.201", features = ["derive"] }
sysinfo = { version = "0.30.10", default-features = false }
toml = "0.8.12"
which = "6.0.1"
quickget_core = { path = "../../quickget/core" }
thiserror = "2.0.8"
itertools = "0.13.0"

[features]
default = ["check_smartcard", "get_qemu_ver", "support_bash_conf"]
Expand Down
23 changes: 23 additions & 0 deletions quickemu/core/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::data::*;
use serde::{Deserialize, Serialize};

#[derive(Default, Debug, Serialize, Deserialize)]
pub struct ConfigFile {
pub guest: GuestOS,
#[serde(default, skip_serializing_if = "is_default")]
pub machine: MachineInfo,
#[serde(default, skip_serializing_if = "is_default")]
pub display: Display,
pub disk_images: Vec<DiskImage>,
pub image_files: Option<Vec<Image>>,
#[serde(default, skip_serializing_if = "is_default")]
pub network: Network,
#[serde(default, skip_serializing_if = "is_default")]
pub monitor: Monitor,
#[serde(default, skip_serializing_if = "is_default")]
pub serial: Monitor,
#[serde(default, skip_serializing_if = "is_default")]
pub io: Io,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub extra_args: Vec<String>,
}
91 changes: 91 additions & 0 deletions quickemu/core/src/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
pub mod display;
pub mod guest;
pub mod image;
pub mod io;
pub mod machine;
pub mod network;

pub use display::*;
pub use guest::*;
pub use image::*;
pub use io::*;
pub use machine::*;
pub use network::*;

use serde::{de, Deserialize, Serialize};
use std::{fmt, path::PathBuf};

pub fn is_default<T: Default + PartialEq>(input: &T) -> bool {
input == &T::default()
}
pub fn is_true(input: &bool) -> bool {
*input
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum BootType {
#[serde(rename = "efi", alias = "EFI", alias = "Efi")]
Efi {
#[serde(default)]
secure_boot: bool,
},
#[serde(rename = "legacy", alias = "Legacy", alias = "bios")]
Legacy,
}
impl Default for BootType {
fn default() -> Self {
Self::Efi { secure_boot: false }
}
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DiskImage {
pub path: PathBuf,
#[serde(deserialize_with = "deserialize_size", default)]
pub size: Option<u64>,
#[serde(default, skip_serializing_if = "is_default")]
pub preallocation: PreAlloc,
pub format: Option<DiskFormat>,
}

struct SizeUnit;
impl<'de> de::Visitor<'de> for SizeUnit {
type Value = Option<u64>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string (ending in a size unit, e.g. M, G, T) or a number (in bytes)")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let mut chars = value.chars().rev();
let mut unit_char = chars.next();
if unit_char.map_or(false, |c| c == 'B') {
unit_char = chars.next();
}
let unit_char = unit_char.ok_or_else(|| de::Error::custom("No unit type was specified"))?;
let size = match unit_char {
'K' => 2u64 << 9,
'M' => 2 << 19,
'G' => 2 << 29,
'T' => 2 << 39,
_ => return Err(de::Error::custom("Unexpected unit type")),
} as f64;

let rem: String = chars.rev().collect();
let size_f: f64 = rem.parse().map_err(de::Error::custom)?;
Ok(Some((size_f * size) as u64))
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Some(value.try_into().map_err(serde::de::Error::custom)?))
}
}
pub fn deserialize_size<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(SizeUnit)
}
Loading

0 comments on commit 0061944

Please sign in to comment.