Skip to main content

minarrow/structs/
column.rs

1// Copyright 2025 Peter Garfield Bower
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! # **Column Module** - *Lazy Column Reference*
16//!
17//! Provides the `Column` type for referencing columns by name without requiring
18//! explicit Field construction. Used for ergonomic column selection APIs.
19//!
20//! # Example
21//! ```rust
22//! use minarrow::{column, Column};
23//!
24//! // Create column references
25//! let col_a = column("employee_id");
26//! let col_b = Column::new("salary");
27//! ```
28
29/// Lazy reference to a column by name
30///
31/// `Column` wraps a string column name and defers resolution until selection time.
32/// This separates user intent ("I want column A") from runtime data (Field with dtype, metadata).
33#[derive(Clone, Debug, PartialEq, Eq, Hash)]
34pub struct Column {
35    name: String,
36}
37
38impl Column {
39    /// Create a new column reference
40    ///
41    /// # Example
42    /// ```rust
43    /// use minarrow::Column;
44    ///
45    /// let col = Column::new("employee_id");
46    /// assert_eq!(col.name(), "employee_id");
47    /// ```
48    pub fn new(name: impl Into<String>) -> Self {
49        Column { name: name.into() }
50    }
51
52    /// Get the column name
53    #[inline]
54    pub fn name(&self) -> &str {
55        &self.name
56    }
57
58    /// Consume and return the column name as a String
59    #[inline]
60    pub fn into_name(self) -> String {
61        self.name
62    }
63}
64
65/// User-facing constructor for column references
66///
67/// # Example
68/// ```rust
69/// use minarrow::column;
70///
71/// let col = column("employee_id");
72/// assert_eq!(col.name(), "employee_id");
73/// ```
74pub fn column(name: impl Into<String>) -> Column {
75    Column::new(name)
76}
77
78impl From<&str> for Column {
79    fn from(name: &str) -> Self {
80        Column::new(name)
81    }
82}
83
84impl From<String> for Column {
85    fn from(name: String) -> Self {
86        Column::new(name)
87    }
88}
89
90impl AsRef<str> for Column {
91    fn as_ref(&self) -> &str {
92        &self.name
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn test_column_creation() {
102        let col_a = column("employee_id");
103        assert_eq!(col_a.name(), "employee_id");
104    }
105
106    #[test]
107    fn test_column_new() {
108        let col = Column::new("salary");
109        assert_eq!(col.name(), "salary");
110    }
111
112    #[test]
113    fn test_column_from_str() {
114        let col_a: Column = "salary".into();
115        assert_eq!(col_a.name(), "salary");
116    }
117
118    #[test]
119    fn test_column_from_string() {
120        let name = String::from("department");
121        let col_a: Column = name.into();
122        assert_eq!(col_a.name(), "department");
123    }
124
125    #[test]
126    fn test_column_into_name() {
127        let col = column("age");
128        let name = col.into_name();
129        assert_eq!(name, "age");
130    }
131
132    #[test]
133    fn test_column_equality() {
134        let col_a = column("id");
135        let col_b = column("id");
136        let col_c = column("name");
137
138        assert_eq!(col_a, col_b);
139        assert_ne!(col_a, col_c);
140    }
141
142    #[test]
143    fn test_column_as_ref() {
144        let col = column("test");
145        let s: &str = col.as_ref();
146        assert_eq!(s, "test");
147    }
148}