This is an automated email from the ASF dual-hosted git repository.

liurenjie1024 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new 609b792e feat: re-export name mapping (#1116)
609b792e is described below

commit 609b792e3f85c835bc9f0898f2ea5ee5eba215e9
Author: Jack <[email protected]>
AuthorDate: Fri Apr 18 14:36:26 2025 +0100

    feat: re-export name mapping (#1116)
    
    ## Which issue does this PR close?
    
    Likely helps towards https://github.com/apache/iceberg-rust/issues/919
    and this was also discussed in
    
[Slack](https://apache-iceberg.slack.com/archives/C05HTENMJG4/p1742385647684059).
    
    ## What changes are included in this PR?
    
    This publicly re-exports the `name_mapping` module to `iceberg::spec`.
    Prior to this, it is private and inaccessible outside of this crate.
    
    ## Are these changes tested?
    
    The main changes here are not functional changes except to visibility.
    
    The additional fields to the `NameMapping` structure have test coverage
    and are covered by prior tests, it is expected that these internal
    fields do **not** show up in the serialised `NameMapping` output, hence
    they are marked with the `serde(skip)` attribute - this is upheld with
    prior tests.
    
    ---------
    
    Co-authored-by: Renjie Liu <[email protected]>
---
 crates/iceberg/src/spec/mod.rs                     |  1 +
 .../spec/{name_mapping.rs => name_mapping/mod.rs}  | 89 +++++++++++++++++-----
 2 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/crates/iceberg/src/spec/mod.rs b/crates/iceberg/src/spec/mod.rs
index 5cf2afa1..10a47574 100644
--- a/crates/iceberg/src/spec/mod.rs
+++ b/crates/iceberg/src/spec/mod.rs
@@ -38,6 +38,7 @@ mod view_version;
 pub use datatypes::*;
 pub use manifest::*;
 pub use manifest_list::*;
+pub use name_mapping::*;
 pub use partition::*;
 pub use schema::*;
 pub use snapshot::*;
diff --git a/crates/iceberg/src/spec/name_mapping.rs 
b/crates/iceberg/src/spec/name_mapping/mod.rs
similarity index 83%
rename from crates/iceberg/src/spec/name_mapping.rs
rename to crates/iceberg/src/spec/name_mapping/mod.rs
index 53d190b4..af18e05b 100644
--- a/crates/iceberg/src/spec/name_mapping.rs
+++ b/crates/iceberg/src/spec/name_mapping/mod.rs
@@ -17,14 +17,31 @@
 
 //! Iceberg name mapping.
 
+use std::sync::Arc;
+
 use serde::{Deserialize, Serialize};
 use serde_with::{serde_as, DefaultOnNull};
 
+/// Property name for name mapping.
+pub const DEFAULT_SCHEMA_NAME_MAPPING: &str = "schema.name-mapping.default";
+
 /// Iceberg fallback field name to ID mapping.
 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
 #[serde(transparent)]
 pub struct NameMapping {
-    pub root: Vec<MappedField>,
+    root: Vec<MappedField>,
+}
+
+impl NameMapping {
+    /// Create a new [`NameMapping`] given a collection of mapped fields.
+    pub fn new(fields: Vec<MappedField>) -> Self {
+        Self { root: fields }
+    }
+
+    /// Get a reference to fields which are to be mapped from name to field ID.
+    pub fn fields(&self) -> &[MappedField] {
+        &self.root
+    }
 }
 
 /// Maps field names to IDs.
@@ -33,12 +50,38 @@ pub struct NameMapping {
 #[serde(rename_all = "kebab-case")]
 pub struct MappedField {
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub field_id: Option<i32>,
-    pub names: Vec<String>,
+    field_id: Option<i32>,
+    names: Vec<String>,
     #[serde(default)]
     #[serde(skip_serializing_if = "Vec::is_empty")]
     #[serde_as(deserialize_as = "DefaultOnNull")]
-    pub fields: Vec<MappedField>,
+    fields: Vec<Arc<MappedField>>,
+}
+
+impl MappedField {
+    /// Create a new [`MappedField`].
+    pub fn new(field_id: Option<i32>, names: Vec<String>, fields: 
Vec<MappedField>) -> Self {
+        Self {
+            field_id,
+            names,
+            fields: fields.into_iter().map(Arc::new).collect(),
+        }
+    }
+
+    /// Iceberg field ID when a field's name is present within `names`.
+    pub fn field_id(&self) -> Option<i32> {
+        self.field_id
+    }
+
+    /// Get a reference to names for a mapped field.
+    pub fn names(&self) -> &[String] {
+        &self.names
+    }
+
+    /// Get a reference to the field mapping for any child fields.
+    pub fn fields(&self) -> &[Arc<MappedField>] {
+        &self.fields
+    }
 }
 
 #[cfg(test)]
@@ -196,15 +239,17 @@ mod tests {
                             field_id: Some(4),
                             names: vec!["latitude".to_string(), 
"lat".to_string()],
                             fields: vec![]
-                        },
+                        }
+                        .into(),
                         MappedField {
                             field_id: Some(5),
                             names: vec!["longitude".to_string(), 
"long".to_string()],
                             fields: vec![]
-                        },
+                        }
+                        .into(),
                     ]
                 }
-            ]
+            ],
         });
     }
 
@@ -234,7 +279,8 @@ mod tests {
                         field_id: Some(5),
                         names: vec!["element".to_string()],
                         fields: vec![],
-                    }],
+                    }
+                    .into()],
                 },
                 MappedField {
                     field_id: Some(6),
@@ -244,7 +290,8 @@ mod tests {
                             field_id: Some(7),
                             names: vec!["key".to_string()],
                             fields: vec![],
-                        },
+                        }
+                        .into(),
                         MappedField {
                             field_id: Some(8),
                             names: vec!["value".to_string()],
@@ -253,14 +300,17 @@ mod tests {
                                     field_id: Some(9),
                                     names: vec!["key".to_string()],
                                     fields: vec![],
-                                },
+                                }
+                                .into(),
                                 MappedField {
                                     field_id: Some(10),
                                     names: vec!["value".to_string()],
                                     fields: vec![],
-                                },
+                                }
+                                .into(),
                             ],
-                        },
+                        }
+                        .into(),
                     ],
                 },
                 MappedField {
@@ -274,14 +324,17 @@ mod tests {
                                 field_id: Some(13),
                                 names: vec!["latitude".to_string()],
                                 fields: vec![],
-                            },
+                            }
+                            .into(),
                             MappedField {
                                 field_id: Some(14),
                                 names: vec!["longitude".to_string()],
                                 fields: vec![],
-                            },
+                            }
+                            .into(),
                         ],
-                    }],
+                    }
+                    .into()],
                 },
                 MappedField {
                     field_id: Some(15),
@@ -291,12 +344,14 @@ mod tests {
                             field_id: Some(16),
                             names: vec!["name".to_string()],
                             fields: vec![],
-                        },
+                        }
+                        .into(),
                         MappedField {
                             field_id: Some(17),
                             names: vec!["age".to_string()],
                             fields: vec![],
-                        },
+                        }
+                        .into(),
                     ],
                 },
             ],

Reply via email to