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)
}
}