Don't allocate a vector when parsing crubit features.

This had been bothering me for a while as a quick hack. Now, with this and the predecessor CL, there should be no copying at all, just reading strings from the JSON and returning integers.

PiperOrigin-RevId: 665583685
Change-Id: Ie8bf81a221632c8927d0c4f278c3ca4876e564fc
diff --git a/common/crubit_feature.rs b/common/crubit_feature.rs
index c9df354..c6a78d4 100644
--- a/common/crubit_feature.rs
+++ b/common/crubit_feature.rs
@@ -90,13 +90,30 @@
     where
         D: serde::Deserializer<'de>,
     {
-        let mut features = flagset::FlagSet::<CrubitFeature>::default();
-        for SerializedCrubitFeature(feature) in
-            <Vec<SerializedCrubitFeature> as Deserialize<'de>>::deserialize(deserializer)?
-        {
-            features |= feature;
+        struct CrubitFeaturesVisitor;
+
+        impl<'de> serde::de::Visitor<'de> for CrubitFeaturesVisitor {
+            type Value = SerializedCrubitFeatures;
+
+            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+                formatter.write_str("a sequence of Crubit feature flag names")
+            }
+
+            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+            where
+                A: serde::de::SeqAccess<'de>,
+            {
+                let mut result = <flagset::FlagSet<CrubitFeature>>::default();
+
+                while let Some(SerializedCrubitFeature(flags)) = seq.next_element()? {
+                    result |= flags;
+                }
+
+                Ok(SerializedCrubitFeatures(result))
+            }
         }
-        Ok(SerializedCrubitFeatures(features))
+
+        deserializer.deserialize_seq(CrubitFeaturesVisitor)
     }
 }