diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c235b432c..5118ce8eab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed bugs +* The `snapshot.max-new-file-size` option can now handle raw integer literals, + interpreted as a number of bytes, where previously it could only handle string + literals. This means that `snapshot.max-new-file-size="1"` and + `snapshot.max-new-file-size=1` are now equivalent. + ## [0.16.0] - 2024-04-03 ### Deprecations diff --git a/cli/tests/test_working_copy.rs b/cli/tests/test_working_copy.rs index e54437b28b..461125b7f6 100644 --- a/cli/tests/test_working_copy.rs +++ b/cli/tests/test_working_copy.rs @@ -20,7 +20,7 @@ fn test_snapshot_large_file() { test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]); let repo_path = test_env.env_root().join("repo"); - test_env.add_config(r#"snapshot.max-new-file-size = "10""#); + test_env.add_config(r#"snapshot.max-new-file-size = 10"#); std::fs::write(repo_path.join("large"), "a lot of text").unwrap(); let stderr = test_env.jj_cmd_failure(&repo_path, &["files"]); insta::assert_snapshot!(stderr, @r###" diff --git a/lib/src/settings.rs b/lib/src/settings.rs index 1eb572469b..380b305b45 100644 --- a/lib/src/settings.rs +++ b/lib/src/settings.rs @@ -331,7 +331,8 @@ impl ConfigResultExt for Result { } /// A size in bytes optionally formatted/serialized with binary prefixes -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, serde::Deserialize)] +#[serde(try_from = "String")] pub struct HumanByteSize(pub u64); impl std::fmt::Display for HumanByteSize { @@ -341,43 +342,18 @@ impl std::fmt::Display for HumanByteSize { } } -impl<'de> serde::Deserialize<'de> for HumanByteSize { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; +impl TryFrom for HumanByteSize { + type Error = String; - struct Visitor; - - impl<'de> serde::de::Visitor<'de> for Visitor { - type Value = HumanByteSize; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(formatter, "a size in bytes with an optional binary unit") - } - - fn visit_u64(self, v: u64) -> Result - where - E: Error, - { - Ok(HumanByteSize(v)) - } - - fn visit_str(self, v: &str) -> Result - where - E: Error, - { - let bytes = parse_human_byte_size(v).map_err(Error::custom)?; + fn try_from(value: String) -> Result { + let res = value.parse::(); + match res { + Ok(bytes) => Ok(HumanByteSize(bytes)), + Err(_) => { + let bytes = parse_human_byte_size(&value)?; Ok(HumanByteSize(bytes)) } } - - if deserializer.is_human_readable() { - deserializer.deserialize_any(Visitor) - } else { - deserializer.deserialize_u64(Visitor) - } } }