use crate::config_error::ConfigError;
use crate::config_values::{member_keys, member_path, safe_integer, text, wrong_kind};
use crate::discarded_prune::{Limits, parse_size};
use monochromatic_jsonc_edit::{JsoncKind, JsoncValue};
pub const SECTION: &str = "discardedCopies";
pub const AGE_KEY: &str = "maxAgeDays";
pub const SIZE_KEY: &str = "maxSize";
fn size_limit(value: &JsoncValue, path: &str) -> Result<u64, ConfigError> {
if matches!(value.kind, JsoncKind::Number { .. }) {
return safe_integer(value, path, 1);
}
if !matches!(value.kind, JsoncKind::Text { .. }) {
return Err(wrong_kind(value, path, "a number of bytes or a size such as \"256m\""));
}
let spelled: String = text(value, path)?;
return parse_size(spelled.as_str()).ok_or_else(|| {
return ConfigError::new(
format!("Configuration key {path} must be a size above zero in bytes or with k, m or g (for example \"256m\"), found {spelled:?}.").as_str(),
);
});
}
pub fn parse_discarded_copies(value: &JsoncValue) -> Result<Limits, ConfigError> {
let Some(entries) = value.entries() else {
return Err(wrong_kind(value, SECTION, "an object"));
};
let keys: Vec<String> = member_keys(entries, SECTION)?;
let mut limits: Limits = Limits::default();
for (index, key) in keys.iter().enumerate() {
let path: String = member_path(SECTION, key.as_str());
let member: &JsoncValue = &entries[index].value;
if key == AGE_KEY {
limits.max_age_days = safe_integer(member, path.as_str(), 1)?;
} else if key == SIZE_KEY {
limits.max_bytes = size_limit(member, path.as_str())?;
} else {
return Err(ConfigError::new(format!("Unknown configuration key: {path}. The accepted keys under {SECTION} are {AGE_KEY}, {SIZE_KEY}.").as_str()));
}
}
return Ok(limits);
}
#[cfg(test)]
#[path = "config_discarded_tests.rs"]
mod tests;