feat: complete scrolling layout controls
This commit is contained in:
1 parent
9d90415e55
commit
5e6c9c3d9d
8 files changed
+537
-30
No files matched your search
+68
-19
@@ -32,6 +32,8 @@ enum LayoutModeValue {
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
struct ScrollingConfig {
|
||||
default_column_width: Option<ColumnWidthValue>,
|
||||
#[serde(default)]
|
||||
width_presets: Vec<ColumnWidthValue>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
@@ -51,7 +53,10 @@ pub enum ConfigError {
|
||||
path: PathBuf,
|
||||
source: toml::de::Error,
|
||||
},
|
||||
InvalidColumnWidth(String),
|
||||
InvalidColumnWidth {
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for ConfigError {
|
||||
@@ -63,9 +68,9 @@ impl fmt::Display for ConfigError {
|
||||
Self::Parse { path, source } => {
|
||||
write!(formatter, "failed to parse {}: {source}", path.display())
|
||||
}
|
||||
Self::InvalidColumnWidth(value) => write!(
|
||||
Self::InvalidColumnWidth { field, value } => write!(
|
||||
formatter,
|
||||
"invalid scrolling.default_column_width {value}; expected a positive number or \"full\""
|
||||
"invalid scrolling.{field} {value}; expected a positive number or \"full\""
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -76,7 +81,7 @@ impl Error for ConfigError {
|
||||
match self {
|
||||
Self::Read { source, .. } => Some(source),
|
||||
Self::Parse { source, .. } => Some(source),
|
||||
Self::InvalidColumnWidth(_) => None,
|
||||
Self::InvalidColumnWidth { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,23 +108,51 @@ impl Config {
|
||||
}
|
||||
|
||||
pub fn default_column_width(&self) -> Result<ColumnWidth, ConfigError> {
|
||||
match self
|
||||
.scrolling
|
||||
.default_column_width
|
||||
.as_ref()
|
||||
.unwrap_or(&ColumnWidthValue::Proportion(0.5))
|
||||
{
|
||||
ColumnWidthValue::Proportion(value) if value.is_finite() && *value > 0.0 => {
|
||||
Ok(ColumnWidth::Proportion(*value))
|
||||
}
|
||||
ColumnWidthValue::Named(value) if value.eq_ignore_ascii_case("full") => {
|
||||
Ok(ColumnWidth::Full)
|
||||
}
|
||||
value => Err(ConfigError::InvalidColumnWidth(match value {
|
||||
parse_column_width(
|
||||
self.scrolling
|
||||
.default_column_width
|
||||
.as_ref()
|
||||
.unwrap_or(&ColumnWidthValue::Proportion(0.5)),
|
||||
"default_column_width",
|
||||
)
|
||||
}
|
||||
|
||||
pub fn width_presets(&self) -> Result<Vec<ColumnWidth>, ConfigError> {
|
||||
if self.scrolling.width_presets.is_empty() {
|
||||
return Ok(vec![
|
||||
ColumnWidth::Proportion(1.0 / 3.0),
|
||||
ColumnWidth::Proportion(0.5),
|
||||
ColumnWidth::Proportion(2.0 / 3.0),
|
||||
ColumnWidth::Full,
|
||||
]);
|
||||
}
|
||||
|
||||
self.scrolling
|
||||
.width_presets
|
||||
.iter()
|
||||
.map(|value| parse_column_width(value, "width_presets"))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_column_width(
|
||||
value: &ColumnWidthValue,
|
||||
field: &'static str,
|
||||
) -> Result<ColumnWidth, ConfigError> {
|
||||
match value {
|
||||
ColumnWidthValue::Proportion(value) if value.is_finite() && *value > 0.0 => {
|
||||
Ok(ColumnWidth::Proportion(*value))
|
||||
}
|
||||
ColumnWidthValue::Named(value) if value.eq_ignore_ascii_case("full") => {
|
||||
Ok(ColumnWidth::Full)
|
||||
}
|
||||
value => Err(ConfigError::InvalidColumnWidth {
|
||||
field,
|
||||
value: match value {
|
||||
ColumnWidthValue::Proportion(value) => value.to_string(),
|
||||
ColumnWidthValue::Named(value) => format!("{value:?}"),
|
||||
})),
|
||||
}
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +198,22 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_width_presets_and_supplies_defaults() {
|
||||
let defaults = parse("");
|
||||
let configured = parse("[scrolling]\nwidth_presets = [0.5, 1.0, \"full\"]");
|
||||
|
||||
assert_eq!(defaults.width_presets().unwrap().len(), 4);
|
||||
assert_eq!(
|
||||
configured.width_presets().unwrap(),
|
||||
vec![
|
||||
ColumnWidth::Proportion(0.5),
|
||||
ColumnWidth::Proportion(1.0),
|
||||
ColumnWidth::Full
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_non_positive_or_unknown_column_widths() {
|
||||
let zero = parse("[scrolling]\ndefault_column_width = 0.0");
|
||||
|
||||
Reference in new issue
Block a user