mirror: simplify MirrorErrors and use iterator
- Remove redundant count field (derive error message from errors.len())
- Change errors from Vec<miette::Report> to Vec<MirrorError>
- Replace explicit loop with filter_map iterator chain

https://claude.ai/code/session_01MtUMXi7Z3GCDWQFY8puWpu
change
commit 3f564fce6a826bc5e1d838c404c55066dd2d1293
author Claude <noreply@anthropic.com>
date
parent 1bcaea9d
diff --git a/quire-server/src/mirror.rs b/quire-server/src/mirror.rs
index 689782a..fb17067 100644
--- a/quire-server/src/mirror.rs
+++ b/quire-server/src/mirror.rs
@@ -9,11 +9,10 @@ use thiserror::Error;
 use crate::quire::Quire;
 
 #[derive(Debug, Error, Diagnostic)]
-#[error("mirror: {count} ref(s) failed")]
+#[error("mirror: {} ref(s) failed", errors.len())]
 struct MirrorErrors {
-    count: usize,
     #[related]
-    errors: Vec<miette::Report>,
+    errors: Vec<MirrorError>,
 }
 
 #[derive(Debug, Error, Diagnostic)]
@@ -56,19 +55,16 @@ pub fn trigger(quire: &Quire, event: &PushEvent) -> miette::Result<()> {
         .transpose()
         .into_diagnostic()?;
 
-    let mut errors: Vec<miette::Report> = vec![];
-
-    for push_ref in event.updated_refs() {
-        if let Err(e) = mirror_ref(&repo, push_ref, mirror_token.as_deref()) {
-            errors.push(miette::Report::from(e));
-        }
-    }
+    let errors: Vec<MirrorError> = event
+        .updated_refs()
+        .into_iter()
+        .filter_map(|push_ref| mirror_ref(&repo, push_ref, mirror_token.as_deref()).err())
+        .collect();
 
     if errors.is_empty() {
         Ok(())
     } else {
-        let count = errors.len();
-        Err(MirrorErrors { count, errors }.into())
+        Err(MirrorErrors { errors }.into())
     }
 }