liurenjie1024 commented on code in PR #12:
URL: https://github.com/apache/iceberg-rust/pull/12#discussion_r1273383207


##########
src/spec/datatypes.rs:
##########
@@ -190,21 +194,83 @@ impl fmt::Display for PrimitiveType {
 }
 
 /// DataType for a specific struct
-#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
+#[derive(Debug, Serialize, PartialEq, Eq, Clone)]
 #[serde(rename = "struct", tag = "type")]
 pub struct StructType {
     /// Struct fields
     fields: Vec<StructField>,
+    /// Lookup for index by field id
+    #[serde(skip_serializing)]
+    id_lookup: BTreeMap<i32, usize>,
+    /// Lookup for index by field name
+    #[serde(skip_serializing)]
+    name_lookup: HashMap<String, usize>,
+}
+
+impl<'de> Deserialize<'de> for StructType {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        #[derive(Deserialize)]
+        #[serde(field_identifier, rename_all = "lowercase")]
+        enum Field {
+            Type,
+            Fields,
+        }
+
+        struct StructTypeVisitor;
+
+        impl<'de> Visitor<'de> for StructTypeVisitor {
+            type Value = StructType;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result 
{
+                formatter.write_str("struct")
+            }
+
+            fn visit_map<V>(self, mut map: V) -> Result<StructType, V::Error>
+            where
+                V: MapAccess<'de>,
+            {
+                let mut fields = None;
+                while let Some(key) = map.next_key()? {
+                    match key {
+                        Field::Type => (),
+                        Field::Fields => {
+                            if fields.is_some() {
+                                return 
Err(de::Error::duplicate_field("fields"));
+                            }
+                            fields = Some(map.next_value()?);
+                        }
+                    }
+                }
+                let fields: Vec<StructField> =
+                    fields.ok_or_else(|| de::Error::missing_field("fields"))?;
+                let id_lookup =
+                    BTreeMap::from_iter(fields.iter().enumerate().map(|(i, x)| 
(x.id, i)));
+                let name_lookup =
+                    HashMap::from_iter(fields.iter().enumerate().map(|(i, x)| 
(x.name.clone(), i)));

Review Comment:
   How about wrapping the construction logic in constructor of `StructType`? 
For example:
   ```rust
   impl StructType {
    pub fn new(fields: Vec<StructField>) -> Self {
     let id_lookup = ...;
   let name_lookup = ...;
    Self {
      ...
   }
    }
   }
   ```
   This way we can avoid duplicating same logic in different places.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to