diff --git a/.gitignore b/.gitignore index 229c61c..95b97d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /.idea -/build \ No newline at end of file +/.vscode +/build diff --git a/src/valid.rs b/src/valid.rs index 71cf843..921f336 100644 --- a/src/valid.rs +++ b/src/valid.rs @@ -50,15 +50,12 @@ pub trait Validator: Sized { Fusion(self.zip(other)) } - fn trace(self, trace: T) -> Valid - where - T: Clone, - { + fn trace(self, trace: impl Into + Clone) -> Valid { let valid = self.to_result(); if let Err(error) = valid { return Valid(Err(error .into_iter() - .map(|cause| cause.trace(trace.clone())) + .map(|cause| cause.trace(trace.clone().into())) .collect())); } @@ -121,10 +118,6 @@ impl Valid { Valid(Err(vec![cause])) } - pub fn from(error: Vec>) -> Self { - Valid(Err(error)) - } - pub fn succeed(a: A) -> Valid { Valid(Ok(a)) } @@ -306,9 +299,9 @@ mod tests { #[test] fn test_trace() { let result = Valid::<(), i32, String>::fail(1) - .trace("A".into()) - .trace("B".into()) - .trace("C".into()); + .trace("A") + .trace("B") + .trace("C"); let expected = Valid::from(vec![Cause { error: 1, @@ -403,4 +396,20 @@ mod tests { assert_eq!(result, Valid::fail(1)); assert_eq!(a, 0); } + + #[test] + fn test_trace_owned_referenced() { + let trace_value = "inner".to_string(); + + let valid: Valid<((), ()), &str, String> = Valid::fail("fail") + .trace(&trace_value) + .zip(Valid::fail("fail 2").trace(trace_value)) + .trace("outer"); + + let causes = valid.to_result().unwrap_err(); + + assert_eq!(causes.len(), 2); + assert_eq!(causes[0].to_string(), "[outer, inner] fail"); + assert_eq!(causes[1].to_string(), "[outer, inner] fail 2"); + } }