Replace SecretString::from_plain/from_file with From impls
Assisted-by: GLM-5.1 via pi
diff --git a/src/ci/mirror.rs b/src/ci/mirror.rs
index 0175796..1af69f2 100644
--- a/src/ci/mirror.rs
+++ b/src/ci/mirror.rs
@@ -481,10 +481,7 @@ mod tests {
};
let mut secrets = HashMap::new();
- secrets.insert(
- "github_token".to_string(),
- SecretString::from_plain("fake_token"),
- );
+ secrets.insert("github_token".to_string(), SecretString::from("fake_token"));
let source = r#"(local ci (require :quire.ci))
(ci.mirror "https://github.com/example/repo.git"
@@ -531,10 +528,7 @@ mod tests {
};
let mut secrets = HashMap::new();
- secrets.insert(
- "github_token".to_string(),
- SecretString::from_plain("fake_token"),
- );
+ secrets.insert("github_token".to_string(), SecretString::from("fake_token"));
// :refs is set and the trigger ref matches, so the mirror
// should push the listed refs verbatim.
@@ -571,10 +565,7 @@ mod tests {
};
let mut secrets = HashMap::new();
- secrets.insert(
- "github_token".to_string(),
- SecretString::from_plain("fake_token"),
- );
+ secrets.insert("github_token".to_string(), SecretString::from("fake_token"));
// Trigger ref is feature, but :refs only lists main — mirror
// should be a no-op.
diff --git a/src/ci/redact.rs b/src/ci/redact.rs
index 54ca4be..f625bfc 100644
--- a/src/ci/redact.rs
+++ b/src/ci/redact.rs
@@ -138,7 +138,7 @@ mod tests {
fn plain_secrets(pairs: &[(&str, &str)]) -> HashMap<String, SecretString> {
pairs
.iter()
- .map(|(k, v)| (k.to_string(), SecretString::from_plain(*v)))
+ .map(|(k, v)| (k.to_string(), SecretString::from(*v)))
.collect()
}
diff --git a/src/ci/runtime.rs b/src/ci/runtime.rs
index 2fc3671..60f759f 100644
--- a/src/ci/runtime.rs
+++ b/src/ci/runtime.rs
@@ -591,7 +591,7 @@ mod tests {
let mut secrets = HashMap::new();
secrets.insert(
"github_token".to_string(),
- SecretString::from_plain("ghp_test_value"),
+ SecretString::from("ghp_test_value"),
);
let source = r#"(local ci (require :quire.ci))
(ci.job :grab [:quire/push] (fn [{: secret}] (secret :github_token)))"#;
@@ -638,7 +638,7 @@ mod tests {
let mut secrets = HashMap::new();
secrets.insert(
"github_token".to_string(),
- SecretString::from_plain("ghp_long_secret_value"),
+ SecretString::from("ghp_long_secret_value"),
);
let source = r#"(local ci (require :quire.ci))
(ci.job :go [:quire/push]
diff --git a/src/secret.rs b/src/secret.rs
index d162d0c..c948738 100644
--- a/src/secret.rs
+++ b/src/secret.rs
@@ -87,18 +87,25 @@ impl std::fmt::Debug for SecretString {
}
}
-impl SecretString {
- /// Build from a plain string literal.
- pub fn from_plain(value: impl Into<String>) -> Self {
- Self(SecretSource::Plain(value.into()))
+impl From<String> for SecretString {
+ fn from(value: String) -> Self {
+ Self(SecretSource::Plain(value))
}
+}
+
+impl From<&str> for SecretString {
+ fn from(value: &str) -> Self {
+ Self(SecretSource::Plain(value.to_string()))
+ }
+}
+impl From<PathBuf> for SecretString {
/// Build from a file path. Contents are read lazily on first [`reveal`].
///
/// [`reveal`]: SecretString::reveal
- pub fn from_file(path: impl Into<PathBuf>) -> Self {
+ fn from(path: PathBuf) -> Self {
Self(SecretSource::File {
- path: path.into(),
+ path,
resolved: OnceLock::new(),
})
}
@@ -135,7 +142,7 @@ mod tests {
#[test]
fn debug_redacts_value() {
- let secret = SecretString::from_plain("super_secret_password");
+ let secret = SecretString::from("super_secret_password");
let debug_output = format!("{secret:?}");
assert_eq!(debug_output, "SecretString(\"<redacted>\")");
assert!(
@@ -146,13 +153,13 @@ mod tests {
#[test]
fn reveal_returns_plain_value() {
- let secret = SecretString::from_plain("plain_value");
+ let secret = SecretString::from("plain_value");
assert_eq!(secret.reveal().unwrap(), "plain_value");
}
#[test]
fn clone_preserves_plain_value() {
- let secret = SecretString::from_plain("clonable");
+ let secret = SecretString::from("clonable");
let cloned = secret.clone();
assert_eq!(cloned.reveal().unwrap(), "clonable");
}
@@ -163,7 +170,7 @@ mod tests {
let path = dir.path().join("token");
fs_err::write(&path, "initial\n").expect("write");
- let secret = SecretString::from_file(&path);
+ let secret = SecretString::from(path.clone());
assert_eq!(secret.reveal().unwrap(), "initial");
// Overwrite the file — cached value should not change.
@@ -177,7 +184,7 @@ mod tests {
let path = dir.path().join("secret");
fs_err::write(&path, "line1\nline2\n").expect("write");
- let secret = SecretString::from_file(&path);
+ let secret = SecretString::from(path.clone());
assert_eq!(secret.reveal().unwrap(), "line1\nline2");
}
@@ -189,13 +196,13 @@ mod tests {
// Any additional trailing newlines are part of the secret.
fs_err::write(&path, "value\n\n\n").expect("write");
- let secret = SecretString::from_file(&path);
+ let secret = SecretString::from(path.clone());
assert_eq!(secret.reveal().unwrap(), "value\n\n");
}
#[test]
fn reveal_errors_on_missing_file() {
- let secret = SecretString::from_file(PathBuf::from("/no/such/file/ever").as_path());
+ let secret = SecretString::from(PathBuf::from("/no/such/file/ever"));
let err = secret.reveal().unwrap_err();
assert!(
matches!(err, Error::Resolve(_)),
@@ -209,7 +216,7 @@ mod tests {
let path = dir.path().join("pw");
fs_err::write(&path, "initial\n").expect("write");
- let original = SecretString::from_file(&path);
+ let original = SecretString::from(path.clone());
assert_eq!(original.reveal().unwrap(), "initial");
// Overwrite after the original cached "initial". The clone gets a fresh
diff --git a/tests/property.rs b/tests/property.rs
index e7d0dbf..3070cae 100644
--- a/tests/property.rs
+++ b/tests/property.rs
@@ -64,7 +64,7 @@ fn updated_refs_excludes_only_zero_sha_deletions(tc: TestCase) {
#[hegel::test]
fn secret_string_debug_never_leaks_plain_value(tc: TestCase) {
let value = tc.draw(text());
- let secret = SecretString::from_plain(value.clone());
+ let secret = SecretString::from(value.clone());
let debug = format!("{secret:?}");
assert_eq!(debug, "SecretString(\"<redacted>\")");
}
@@ -84,7 +84,7 @@ fn secret_string_from_file_strips_one_trailing_newline(tc: TestCase) {
let path = dir.path().join("secret");
fs_err::write(&path, &content).expect("write");
- let revealed = SecretString::from_file(&path)
+ let revealed = SecretString::from(path.clone())
.reveal()
.expect("reveal")
.to_string();
@@ -124,7 +124,7 @@ fn push_event_updated_refs_is_subtractive(tc: TestCase) {
fn plain_secrets(pairs: &[(&str, &str)]) -> HashMap<String, SecretString> {
pairs
.iter()
- .map(|(k, v)| (k.to_string(), SecretString::from_plain(*v)))
+ .map(|(k, v)| (k.to_string(), SecretString::from(*v)))
.collect()
}
@@ -153,7 +153,7 @@ fn resolved_registry(tc: TestCase) -> SecretRegistry {
let entries = tc.draw(unique_secret_entries());
let mut map = HashMap::new();
for (name, value) in &entries {
- map.insert(name.clone(), SecretString::from_plain(value.clone()));
+ map.insert(name.clone(), SecretString::from(value.clone()));
}
let mut reg = SecretRegistry::new(map);
// Resolve all secrets so they're registered for redaction.
@@ -169,7 +169,7 @@ fn text_with_secrets(tc: TestCase) -> (SecretRegistry, String) {
let mut map = HashMap::new();
let mut long_values: Vec<String> = Vec::new();
for (name, value) in &entries {
- map.insert(name.clone(), SecretString::from_plain(value.clone()));
+ map.insert(name.clone(), SecretString::from(value.clone()));
if value.len() >= MIN_REDACT_LEN {
long_values.push(value.clone());
}
@@ -198,7 +198,7 @@ fn redact_never_contains_revealed_long_values(tc: TestCase) {
let mut map = HashMap::new();
let mut long_values: Vec<String> = Vec::new();
for (name, value) in &entries {
- map.insert(name.clone(), SecretString::from_plain(value.clone()));
+ map.insert(name.clone(), SecretString::from(value.clone()));
if value.len() >= MIN_REDACT_LEN {
long_values.push(value.clone());
}
@@ -256,7 +256,7 @@ fn redact_unresolved_registry_is_identity(tc: TestCase) {
let entries = tc.draw(unique_secret_entries());
let map: HashMap<String, SecretString> = entries
.into_iter()
- .map(|(k, v)| (k, SecretString::from_plain(v)))
+ .map(|(k, v)| (k, SecretString::from(v)))
.collect();
let reg = SecretRegistry::new(map);
let text = tc.draw(text());
@@ -286,7 +286,7 @@ fn redact_output_never_shows_long_secret_values(tc: TestCase) {
let entries = tc.draw(unique_secret_entries());
let mut map = HashMap::new();
for (name, value) in &entries {
- map.insert(name.clone(), SecretString::from_plain(value.clone()));
+ map.insert(name.clone(), SecretString::from(value.clone()));
}
let mut reg = SecretRegistry::new(map);
for (name, _) in &entries {