Implement Display for Config

This commit is contained in:
Wildan M
2026-01-31 04:15:10 +07:00
parent 64f46052db
commit d40619d66c
4 changed files with 90 additions and 4 deletions
+35
View File
@@ -1,3 +1,5 @@
use std::fmt::Display;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct FileConfig {
pub path: String,
@@ -46,3 +48,36 @@ impl FileConfig {
self
}
}
impl Display for FileConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.path)?;
if self.symlink {
write!(f, " -> {}", self.data)?;
} else if self.directory {
write!(f, " type=dir")?;
if self.recursive_chown {
write!(f, " chown=yes")?;
}
} else {
write!(
f,
" size={}B",
arg_parser::to_human_readable_string(self.data.len() as u64)
)?;
if self.postinstall {
write!(f, "!")?;
}
}
if let Some(uid) = self.uid {
write!(f, " uid={}", uid)?;
}
if let Some(uid) = self.uid {
write!(f, " gid={}", uid)?;
}
if let Some(mode) = self.mode {
write!(f, " mode={:3o}", mode)?;
}
Ok(())
}
}
+27 -3
View File
@@ -1,9 +1,11 @@
use std::collections::BTreeMap;
use std::fmt::Display;
use std::fs;
use std::mem;
use std::path::{Path, PathBuf};
use anyhow::bail;
use anyhow::Context;
use anyhow::Result;
pub mod file;
@@ -35,11 +37,11 @@ impl Config {
Ok(config_data) => match toml::from_str(&config_data) {
Ok(config) => config,
Err(err) => {
bail!("{}: failed to decode: {}", path.display(), err);
bail!("failed to decode '{}': {}", path.display(), err);
}
},
Err(err) => {
bail!("{}: failed to read: {}", path.display(), err);
bail!("failed to read '{}': {}", path.display(), err);
}
};
@@ -47,7 +49,10 @@ impl Config {
let mut configs = mem::take(&mut config.include)
.into_iter()
.map(|path| Config::from_file(&config_dir.join(path)))
.map(|path| {
Config::from_file(&config_dir.join(&path))
.with_context(|| format!("Importing from {}", path.display()))
})
.collect::<Result<Vec<Config>>>()?;
configs.push(config); // Put ourself last to ensure that it overwrites anything else.
@@ -90,3 +95,22 @@ impl Config {
}
}
}
impl Display for Config {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "files:")?;
for file in &self.files {
writeln!(f, "- {}", file)?;
}
writeln!(f, "users:")?;
for (name, user) in &self.users {
writeln!(f, "- {}:{}", name, user)?;
}
write!(f, "packages: ")?;
for name in self.packages.keys() {
write!(f, " {}", name)?;
}
writeln!(f, "")?;
Ok(())
}
}
+27
View File
@@ -1,3 +1,5 @@
use std::fmt::Display;
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct UserConfig {
pub password: Option<String>,
@@ -14,3 +16,28 @@ pub struct GroupConfig {
// FIXME move this to the UserConfig struct as extra_groups
pub members: Vec<String>,
}
impl Display for UserConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(uid) = &self.uid {
write!(f, " uid={}", uid)?;
}
if let Some(gid) = &self.gid {
write!(f, " gid={}", gid)?;
}
if let Some(name) = &self.name {
write!(f, " name={}", name)?;
}
if let Some(home) = &self.home {
write!(f, " home={}", home)?;
}
if let Some(shell) = &self.shell {
write!(f, " shell={}", shell)?;
}
if self.password.as_ref().is_some_and(|s| !s.is_empty()) {
write!(f, " password=yes")?;
}
Ok(())
}
}
+1 -1
View File
@@ -817,7 +817,7 @@ pub fn try_fast_install<D: redoxfs::Disk, F: FnMut(u64, u64)>(
}
fn install_inner(config: Config, output: &Path) -> Result<()> {
println!("Install {config:#?} to {}", output.display());
println!("Installing to {}:\n{}", output.display(), config);
let cookbook = config.general.cookbook.clone();
let cookbook = cookbook.as_ref().map(|p| p.as_str());
if output.is_dir() {