#[repr(C, align(64))]pub struct Table {
pub cols: Vec<FieldArray>,
pub n_rows: usize,
pub name: String,
}Expand description
§Table
§Description
- Standard columnar table with named columns (
FieldArray), a fixed number of rows, and an optional logical table name. - All columns are required to be equal length and have consistent schema.
- Supports zero-copy slicing, efficient iteration, and bulk operations.
- Equivalent to the
RecordBatchin Apache Arrow.
§Structure
cols: A vector ofFieldArray, each representing a column with metadata and data.n_rows: The logical number of rows (guaranteed equal for all columns).name: Optional logical name or alias for this table instance.
§Usage
- Use
Tableas a general-purpose, in-memory columnar data container. - Good for analytics, and transformation pipelines.
- For batched/partitioned tables, see [
SuperTable] or windowed/chunked abstractions. - Cast into Polars dataframe via
.to_polars()or Apache Arrow via.to_apache_arrow() - FFI-compatible
§Notes
- Table instances are typically lightweight to clone and pass by value.
- For mutation, construct a new table or replace individual columns as needed.
- There is an alias
RecordBatchunder crate::aliases::RecordBatch
§Example
use minarrow::{FieldArray, Print, Table, arr_i32, arr_str32, vec64};
let col1 = FieldArray::from_arr("numbers", arr_i32![1, 2, 3]);
let col2 = FieldArray::from_arr("letters", arr_str32!["x", "y", "z"]);
let mut tbl = Table::new("Demo".into(), vec![col1, col2].into());
tbl.print();Fields§
§cols: Vec<FieldArray>FieldArrays representing named columns.
n_rows: usizeNumber of rows in the table.
name: StringTable name
Implementations§
Source§impl Table
impl Table
Sourcepub fn new(name: String, cols: Option<Vec<FieldArray>>) -> Self
pub fn new(name: String, cols: Option<Vec<FieldArray>>) -> Self
Constructs a new Table with a specified name and optional columns.
If cols is provided, the number of rows will be inferred from the first column.
Examples found in repository?
102fn create_sample_table() -> Table {
103 // Create id column
104 let mut id_arr = IntegerArray::<i32>::default();
105 for i in 0..10 {
106 id_arr.push(i);
107 }
108
109 // Create name column
110 let mut name_arr = StringArray::<u32>::default();
111 let names = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Henry", "Iris", "Jack"];
112 for name in names {
113 name_arr.push(name.to_string());
114 }
115
116 // Create age column
117 let mut age_arr = IntegerArray::<i32>::default();
118 for i in 0..10 {
119 age_arr.push(20 + (i * 3) as i32);
120 }
121
122 let col_id = FieldArray::from_arr("id", Array::from_int32(id_arr));
123 let col_name = FieldArray::from_arr("name", Array::from_string32(name_arr));
124 let col_age = FieldArray::from_arr("age", Array::from_int32(age_arr));
125
126 Table::new("People".to_string(), Some(vec![col_id, col_name, col_age]))
127}More examples
280fn test_table_broadcasting() {
281 println!("┌─ Test 9: Table Broadcasting");
282 println!(
283 "│ Operation: Table{{col1:[1,2,3], col2:[4,5,6]}} + Table{{col1:[10,10,10], col2:[20,20,20]}}"
284 );
285 println!("│ Expected: Table{{col1:[11,12,13], col2:[24,25,26]}}");
286
287 // Create first table with two columns
288 let arr1_col1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2, 3]));
289 let arr1_col2 = Array::from_int32(IntegerArray::from_slice(&vec64![4, 5, 6]));
290 let fa1_col1 = minarrow::FieldArray::from_arr("col1", arr1_col1);
291 let fa1_col2 = minarrow::FieldArray::from_arr("col2", arr1_col2);
292 let mut table1 = Table::new("table1".to_string(), None);
293 table1.add_col(fa1_col1);
294 table1.add_col(fa1_col2);
295
296 // Create second table with matching structure
297 let arr2_col1 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10, 10]));
298 let arr2_col2 = Array::from_int32(IntegerArray::from_slice(&vec64![20, 20, 20]));
299 let fa2_col1 = minarrow::FieldArray::from_arr("col1", arr2_col1);
300 let fa2_col2 = minarrow::FieldArray::from_arr("col2", arr2_col2);
301 let mut table2 = Table::new("table2".to_string(), None);
302 table2.add_col(fa2_col1);
303 table2.add_col(fa2_col2);
304
305 match Value::Table(Arc::new(table1)) + Value::Table(Arc::new(table2)) {
306 Ok(Value::Table(result)) => {
307 if let Array::NumericArray(NumericArray::Int32(col1)) = &result.cols[0].array {
308 println!("│ Result col1: {:?}", col1.data.as_slice());
309 }
310 if let Array::NumericArray(NumericArray::Int32(col2)) = &result.cols[1].array {
311 println!("│ Result col2: {:?}", col2.data.as_slice());
312 }
313 println!("└─ ✓ Passed\n");
314 }
315 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
316 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
317 }
318}
319
320/// Test ArrayView broadcasting - efficient windowed operations
321fn test_array_view_broadcasting() {
322 #[cfg(feature = "views")]
323 {
324 println!("┌─ Test 10: ArrayView Broadcasting");
325 println!("│ Operation: ArrayView([2,3,4]) + ArrayView([10,10,10])");
326 println!("│ Expected: Array([12,13,14])");
327
328 // Create an array and a view into it
329 let arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2, 3, 4, 5]));
330 let view1 = ArrayV::new(arr1, 1, 3); // View of elements [2,3,4]
331
332 let arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10, 10]));
333 let view2 = ArrayV::new(arr2, 0, 3);
334
335 match Value::ArrayView(Arc::new(view1)) + Value::ArrayView(Arc::new(view2)) {
336 Ok(Value::Array(arr_arc)) => {
337 if let Array::NumericArray(NumericArray::Int32(result)) = arr_arc.as_ref() {
338 println!("│ Result: {:?}", result.data.as_slice());
339 println!("└─ ✓ Passed\n");
340 } else {
341 println!("└─ ✗ Error: Unexpected array type\n");
342 }
343 }
344 Ok(_) => println!("└─ ✗ Error: Unexpected result type\n"),
345 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
346 }
347 }
348
349 #[cfg(not(feature = "views"))]
350 {
351 println!("┌─ Test 10: ArrayView Broadcasting");
352 println!("└─ ⊘ Skipped (views feature not enabled)\n");
353 }
354}
355
356/// Test SuperArray broadcasting - chunked array operations
357fn test_super_array_broadcasting() {
358 #[cfg(feature = "chunked")]
359 {
360 println!("┌─ Test 11: SuperArray (Chunked) Broadcasting");
361 println!("│ Operation: SuperArray{{[1,2],[3,4]}} * SuperArray{{[2,2],[2,2]}}");
362 println!("│ Expected: SuperArray{{[2,4],[6,8]}}");
363
364 // Create chunked arrays (multiple field array chunks)
365 let chunk1_a = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2]));
366 let chunk2_a = Array::from_int32(IntegerArray::from_slice(&vec64![3, 4]));
367 let fa1 = minarrow::FieldArray::from_arr("chunk1", chunk1_a);
368 let fa2 = minarrow::FieldArray::from_arr("chunk1", chunk2_a);
369 let super_arr1 = SuperArray::from_field_array_chunks(vec![fa1, fa2]);
370
371 let chunk1_b = Array::from_int32(IntegerArray::from_slice(&vec64![2, 2]));
372 let chunk2_b = Array::from_int32(IntegerArray::from_slice(&vec64![2, 2]));
373 let fa3 = minarrow::FieldArray::from_arr("chunk1", chunk1_b);
374 let fa4 = minarrow::FieldArray::from_arr("chunk1", chunk2_b);
375 let super_arr2 = SuperArray::from_field_array_chunks(vec![fa3, fa4]);
376
377 match Value::SuperArray(Arc::new(super_arr1)) * Value::SuperArray(Arc::new(super_arr2)) {
378 Ok(Value::SuperArray(result)) => {
379 println!("│ Result with {} chunks:", result.len());
380 for i in 0..result.len() {
381 if let Some(fa) = result.chunk(i) {
382 if let Array::NumericArray(NumericArray::Int32(arr)) = &fa.array {
383 println!("│ Chunk {}: {:?}", i, arr.data.as_slice());
384 }
385 }
386 }
387 println!("└─ ✓ Passed\n");
388 }
389 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
390 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
391 }
392 }
393
394 #[cfg(not(feature = "chunked"))]
395 {
396 println!("┌─ Test 11: SuperArray (Chunked) Broadcasting");
397 println!("└─ ⊘ Skipped (chunked feature not enabled)\n");
398 }
399}
400
401/// Test Cube broadcasting - 3D tensor operations
402fn test_cube_broadcasting() {
403 #[cfg(feature = "cube")]
404 {
405 println!("┌─ Test 12: Cube (3D) Broadcasting");
406 println!("│ Operation: Cube{{2 tables}} + Cube{{2 tables}}");
407 println!("│ Expected: Element-wise addition across all tables");
408
409 // Create first cube with 2 tables
410 // First, create columns for table 1
411 let t1_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2]));
412 let t1_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![3, 4]));
413 let t1_fa1 = minarrow::FieldArray::from_arr("col1", t1_arr1);
414 let t1_fa2 = minarrow::FieldArray::from_arr("col2", t1_arr2);
415
416 // Create columns for cube1 via constructor
417 let mut cube1 = Cube::new("cube1".to_string(), Some(vec![t1_fa1, t1_fa2]), None);
418
419 // Add second table to cube1
420 let t2_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![5, 6]));
421 let t2_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![7, 8]));
422 let t2_fa1 = minarrow::FieldArray::from_arr("col1", t2_arr1);
423 let t2_fa2 = minarrow::FieldArray::from_arr("col2", t2_arr2);
424 let mut table2 = Table::new("t2".to_string(), None);
425 table2.add_col(t2_fa1);
426 table2.add_col(t2_fa2);
427 cube1.add_table(table2);
428
429 // Create second cube
430 let t3_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10]));
431 let t3_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![20, 20]));
432 let t3_fa1 = minarrow::FieldArray::from_arr("col1", t3_arr1);
433 let t3_fa2 = minarrow::FieldArray::from_arr("col2", t3_arr2);
434 let mut cube2 = Cube::new("cube2".to_string(), Some(vec![t3_fa1, t3_fa2]), None);
435
436 let t4_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![30, 30]));
437 let t4_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![40, 40]));
438 let t4_fa1 = minarrow::FieldArray::from_arr("col1", t4_arr1);
439 let t4_fa2 = minarrow::FieldArray::from_arr("col2", t4_arr2);
440 let mut table4 = Table::new("t4".to_string(), None);
441 table4.add_col(t4_fa1);
442 table4.add_col(t4_fa2);
443 cube2.add_table(table4);
444
445 match Value::Cube(Arc::new(cube1)) + Value::Cube(Arc::new(cube2)) {
446 Ok(Value::Cube(result)) => {
447 println!("│ Result cube with {} tables:", result.n_tables());
448 for i in 0..result.n_tables() {
449 println!("│ Table {}:", i);
450 if let Some(table) = result.table(i) {
451 for j in 0..table.n_cols() {
452 let col = &table.cols[j];
453 if let Array::NumericArray(NumericArray::Int32(arr)) = &col.array {
454 println!("│ Column {}: {:?}", j, arr.data.as_slice());
455 }
456 }
457 }
458 }
459 println!("└─ ✓ Passed\n");
460 }
461 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
462 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
463 }
464 }
465
466 #[cfg(not(feature = "cube"))]
467 {
468 println!("┌─ Test 12: Cube (3D) Broadcasting");
469 println!("└─ ⊘ Skipped (cube feature not enabled)\n");
470 }
471}13fn main() {
14 // Inner arrays
15
16 // Numeric
17 let col_i32 = IntArr::<i32>::from_slice(&[1, 2, 3, 4, 5]);
18 let col_u32 = IntArr::<u32>::from_slice(&[100, 200, 300, 400, 500]);
19 let col_i64 = IntArr::<i64>::from_slice(&[10, 20, 30, 40, 50]);
20 let col_u64 = IntArr::<u64>::from_slice(&[101, 201, 301, 401, 501]);
21 let col_f32 = FltArr::<f32>::from_slice(&[1.1, 2.2, 3.3, 4.4, 5.5]);
22 let col_f64 = FltArr::<f64>::from_slice(&[2.2, 3.3, 4.4, 5.5, 6.6]);
23
24 // Boolean with nulls
25 let mut col_bool = BoolArr::from_slice(&[true, false, true, false, true]);
26 col_bool.set_null_mask(Some(Bitmask::from_bools(&[true, true, true, false, true])));
27
28 // String and Dictionary/Categorical
29 let col_str32 = StrArr::<u32>::from_slice(&["red", "blue", "green", "yellow", "purple"]);
30 let col_cat32 = CatArr::<u32>::from_values(
31 ["apple", "banana", "cherry", "banana", "apple"]
32 .iter()
33 .copied(),
34 );
35
36 // Datetime
37 #[cfg(feature = "datetime")]
38 let col_dt32 = DatetimeArray::<i32>::from_slice(
39 &[1000, 2000, 3000, 4000, 5000],
40 Some(TimeUnit::Milliseconds),
41 );
42 #[cfg(feature = "datetime")]
43 let col_dt64 = DatetimeArray::<i64>::from_slice(
44 &[
45 1_000_000_000,
46 2_000_000_000,
47 3_000_000_000,
48 4_000_000_000,
49 5_000_000_000,
50 ],
51 Some(TimeUnit::Nanoseconds),
52 );
53
54 // FieldArray (column) construction
55 let fa_i32 = FieldArray::from_arr("int32_col", col_i32);
56 let fa_u32 = FieldArray::from_arr("uint32_col", col_u32);
57 let fa_i64 = FieldArray::from_arr("int64_col", col_i64);
58 let fa_u64 = FieldArray::from_arr("uint64_col", col_u64);
59 let fa_f32 = FieldArray::from_arr("float32_col", col_f32);
60 let fa_f64 = FieldArray::from_arr("float64_col", col_f64);
61 let fa_bool = FieldArray::from_arr("bool_col", col_bool);
62 let fa_str32 = FieldArray::from_arr("utf8_col", col_str32);
63 let fa_cat32 = FieldArray::from_arr("dict32_col", col_cat32);
64 #[cfg(feature = "datetime")]
65 let fa_dt32 = FieldArray::from_arr("datetime32_col", col_dt32);
66 #[cfg(feature = "datetime")]
67 let fa_dt64 = FieldArray::from_arr("datetime64_col", col_dt64);
68
69 // Build Table
70 let mut tbl = Table::new("MyTable".to_string(), None);
71 tbl.add_col(fa_i32);
72 tbl.add_col(fa_u32);
73 tbl.add_col(fa_i64);
74 tbl.add_col(fa_u64);
75 tbl.add_col(fa_f32);
76 tbl.add_col(fa_f64);
77 tbl.add_col(fa_bool);
78 tbl.add_col(fa_str32);
79 tbl.add_col(fa_cat32);
80 #[cfg(feature = "datetime")]
81 tbl.add_col(fa_dt32);
82 #[cfg(feature = "datetime")]
83 tbl.add_col(fa_dt64);
84
85 // Print the table
86 tbl.print();
87}31 fn build_minarrow_table() -> Table {
32 // Arrays
33 #[cfg(feature = "extended_numeric_types")]
34 let arr_int8 = Arc::new(minarrow::IntegerArray::<i8>::from_slice(&[1, 2, -1])) as Arc<_>;
35 #[cfg(feature = "extended_numeric_types")]
36 let arr_int16 =
37 Arc::new(minarrow::IntegerArray::<i16>::from_slice(&[10, 20, -10])) as Arc<_>;
38 let arr_int32 =
39 Arc::new(minarrow::IntegerArray::<i32>::from_slice(&[100, 200, -100])) as Arc<_>;
40 let arr_int64 = Arc::new(minarrow::IntegerArray::<i64>::from_slice(&[
41 1000, 2000, -1000,
42 ])) as Arc<_>;
43
44 #[cfg(feature = "extended_numeric_types")]
45 let arr_uint8 = Arc::new(minarrow::IntegerArray::<u8>::from_slice(&[1, 2, 255]))
46 as Arc<minarrow::IntegerArray<u8>>;
47 #[cfg(feature = "extended_numeric_types")]
48 let arr_uint16 = Arc::new(minarrow::IntegerArray::<u16>::from_slice(&[1, 2, 65535]))
49 as Arc<minarrow::IntegerArray<u16>>;
50 let arr_uint32 = Arc::new(minarrow::IntegerArray::<u32>::from_slice(&[
51 1, 2, 4294967295,
52 ])) as Arc<minarrow::IntegerArray<u32>>;
53 let arr_uint64 = Arc::new(minarrow::IntegerArray::<u64>::from_slice(&[
54 1,
55 2,
56 18446744073709551615,
57 ])) as Arc<minarrow::IntegerArray<u64>>;
58
59 let arr_float32 = Arc::new(minarrow::FloatArray::<f32>::from_slice(&[1.5, -0.5, 0.0]))
60 as Arc<minarrow::FloatArray<f32>>;
61 let arr_float64 = Arc::new(minarrow::FloatArray::<f64>::from_slice(&[1.0, -2.0, 0.0]))
62 as Arc<minarrow::FloatArray<f64>>;
63
64 let arr_bool = Arc::new(minarrow::BooleanArray::<()>::from_slice(&[
65 true, false, true,
66 ])) as Arc<minarrow::BooleanArray<()>>;
67
68 let arr_string32 = Arc::new(minarrow::StringArray::<u32>::from_slice(&[
69 "abc", "def", "",
70 ])) as Arc<minarrow::StringArray<u32>>;
71 let arr_categorical32 = Arc::new(minarrow::CategoricalArray::<u32>::from_slices(
72 &[0, 1, 2],
73 &["A".to_string(), "B".to_string(), "C".to_string()],
74 )) as Arc<minarrow::CategoricalArray<u32>>;
75
76 #[cfg(feature = "datetime")]
77 let arr_datetime32 = Arc::new(minarrow::DatetimeArray::<i32> {
78 data: minarrow::Buffer::<i32>::from_slice(&[
79 1_600_000_000 / 86_400,
80 1_600_000_001 / 86_400,
81 1_600_000_002 / 86_400,
82 ]),
83 null_mask: None,
84 time_unit: TimeUnit::Days,
85 });
86 #[cfg(feature = "datetime")]
87 let arr_datetime64 = Arc::new(minarrow::DatetimeArray::<i64> {
88 data: minarrow::Buffer::<i64>::from_slice(&[
89 1_600_000_000_000,
90 1_600_000_000_001,
91 1_600_000_000_002,
92 ]),
93 null_mask: None,
94 time_unit: TimeUnit::Milliseconds,
95 }) as Arc<_>;
96
97 // Wrap in Array enums
98 #[cfg(feature = "extended_numeric_types")]
99 let minarr_int8 = Array::NumericArray(NumericArray::Int8(arr_int8));
100 #[cfg(feature = "extended_numeric_types")]
101 let minarr_int16 = Array::NumericArray(NumericArray::Int16(arr_int16));
102 let minarr_int32 = Array::NumericArray(NumericArray::Int32(arr_int32));
103 let minarr_int64 = Array::NumericArray(NumericArray::Int64(arr_int64));
104 #[cfg(feature = "extended_numeric_types")]
105 let minarr_uint8 = Array::NumericArray(NumericArray::UInt8(arr_uint8));
106 #[cfg(feature = "extended_numeric_types")]
107 let minarr_uint16 = Array::NumericArray(NumericArray::UInt16(arr_uint16));
108 let minarr_uint32 = Array::NumericArray(NumericArray::UInt32(arr_uint32));
109 let minarr_uint64 = Array::NumericArray(NumericArray::UInt64(arr_uint64));
110 let minarr_float32 = Array::NumericArray(NumericArray::Float32(arr_float32));
111 let minarr_float64 = Array::NumericArray(NumericArray::Float64(arr_float64));
112 let minarr_bool = Array::BooleanArray(arr_bool);
113 let minarr_string32 = Array::TextArray(TextArray::String32(arr_string32));
114 let minarr_categorical32 = Array::TextArray(TextArray::Categorical32(arr_categorical32));
115 #[cfg(feature = "datetime")]
116 let minarr_datetime32 = Array::TemporalArray(TemporalArray::Datetime32(arr_datetime32));
117 #[cfg(feature = "datetime")]
118 let minarr_datetime64 = Array::TemporalArray(TemporalArray::Datetime64(arr_datetime64));
119
120 // Fields
121 #[cfg(feature = "extended_numeric_types")]
122 let field_int8 = Field::new("int8", ArrowType::Int8, false, None);
123 #[cfg(feature = "extended_numeric_types")]
124 let field_int16 = Field::new("int16", ArrowType::Int16, false, None);
125 let field_int32 = Field::new("int32", ArrowType::Int32, false, None);
126 let field_int64 = Field::new("int64", ArrowType::Int64, false, None);
127 #[cfg(feature = "extended_numeric_types")]
128 let field_uint8 = Field::new("uint8", ArrowType::UInt8, false, None);
129 #[cfg(feature = "extended_numeric_types")]
130 let field_uint16 = Field::new("uint16", ArrowType::UInt16, false, None);
131 let field_uint32 = Field::new("uint32", ArrowType::UInt32, false, None);
132 let field_uint64 = Field::new("uint64", ArrowType::UInt64, false, None);
133 let field_float32 = Field::new("float32", ArrowType::Float32, false, None);
134 let field_float64 = Field::new("float64", ArrowType::Float64, false, None);
135 let field_bool = Field::new("bool", ArrowType::Boolean, false, None);
136 let field_string32 = Field::new("string32", ArrowType::String, false, None);
137 let field_categorical32 = Field::new(
138 "categorical32",
139 ArrowType::Dictionary(CategoricalIndexType::UInt32),
140 false,
141 None,
142 );
143 #[cfg(feature = "datetime")]
144 let field_datetime32 = Field::new("dt32", ArrowType::Date32, false, None);
145 #[cfg(feature = "datetime")]
146 let field_datetime64 = Field::new("dt64", ArrowType::Date64, false, None);
147
148 // FieldArrays
149 #[cfg(feature = "extended_numeric_types")]
150 let fa_int8 = FieldArray::new(field_int8, minarr_int8);
151 #[cfg(feature = "extended_numeric_types")]
152 let fa_int16 = FieldArray::new(field_int16, minarr_int16);
153 let fa_int32 = FieldArray::new(field_int32, minarr_int32);
154 let fa_int64 = FieldArray::new(field_int64, minarr_int64);
155 #[cfg(feature = "extended_numeric_types")]
156 let fa_uint8 = FieldArray::new(field_uint8, minarr_uint8);
157 #[cfg(feature = "extended_numeric_types")]
158 let fa_uint16 = FieldArray::new(field_uint16, minarr_uint16);
159 let fa_uint32 = FieldArray::new(field_uint32, minarr_uint32);
160 let fa_uint64 = FieldArray::new(field_uint64, minarr_uint64);
161 let fa_float32 = FieldArray::new(field_float32, minarr_float32);
162 let fa_float64 = FieldArray::new(field_float64, minarr_float64);
163 let fa_bool = FieldArray::new(field_bool, minarr_bool);
164 let fa_string32 = FieldArray::new(field_string32, minarr_string32);
165 let fa_categorical32 = FieldArray::new(field_categorical32, minarr_categorical32);
166 #[cfg(feature = "datetime")]
167 let fa_datetime32 = FieldArray::new(field_datetime32, minarr_datetime32);
168 #[cfg(feature = "datetime")]
169 let fa_datetime64 = FieldArray::new(field_datetime64, minarr_datetime64);
170
171 // Build table
172 let mut cols = Vec::new();
173 #[cfg(feature = "extended_numeric_types")]
174 {
175 cols.push(fa_int8);
176 cols.push(fa_int16);
177 }
178 cols.push(fa_int32);
179 cols.push(fa_int64);
180 #[cfg(feature = "extended_numeric_types")]
181 {
182 cols.push(fa_uint8);
183 cols.push(fa_uint16);
184 }
185 cols.push(fa_uint32);
186 cols.push(fa_uint64);
187 cols.push(fa_float32);
188 cols.push(fa_float64);
189 cols.push(fa_bool);
190 cols.push(fa_string32);
191 cols.push(fa_categorical32);
192 #[cfg(feature = "datetime")]
193 {
194 cols.push(fa_datetime32);
195 cols.push(fa_datetime64);
196 }
197 Table::new("polars_ffi_test".to_string(), Some(cols))
198 }27 pub(crate) fn run_example() {
28 // ---- 1. Build a Minarrow Table with all types ----
29
30 #[cfg(feature = "extended_numeric_types")]
31 let arr_int8 = Arc::new(minarrow::IntegerArray::<i8>::from_slice(&[1, 2, -1])) as Arc<_>;
32 #[cfg(feature = "extended_numeric_types")]
33 let arr_int16 =
34 Arc::new(minarrow::IntegerArray::<i16>::from_slice(&[10, 20, -10])) as Arc<_>;
35 let arr_int32 =
36 Arc::new(minarrow::IntegerArray::<i32>::from_slice(&[100, 200, -100])) as Arc<_>;
37 let arr_int64 = Arc::new(minarrow::IntegerArray::<i64>::from_slice(&[
38 1000, 2000, -1000,
39 ])) as Arc<_>;
40
41 #[cfg(feature = "extended_numeric_types")]
42 let arr_uint8 = Arc::new(minarrow::IntegerArray::<u8>::from_slice(&[1, 2, 255]))
43 as Arc<minarrow::IntegerArray<u8>>;
44 #[cfg(feature = "extended_numeric_types")]
45 let arr_uint16 = Arc::new(minarrow::IntegerArray::<u16>::from_slice(&[1, 2, 65535]))
46 as Arc<minarrow::IntegerArray<u16>>;
47 let arr_uint32 = Arc::new(minarrow::IntegerArray::<u32>::from_slice(&[
48 1, 2, 4294967295,
49 ])) as Arc<minarrow::IntegerArray<u32>>;
50 let arr_uint64 = Arc::new(minarrow::IntegerArray::<u64>::from_slice(&[
51 1,
52 2,
53 18446744073709551615,
54 ])) as Arc<minarrow::IntegerArray<u64>>;
55
56 let arr_float32 = Arc::new(minarrow::FloatArray::<f32>::from_slice(&[1.5, -0.5, 0.0]))
57 as Arc<minarrow::FloatArray<f32>>;
58 let arr_float64 = Arc::new(minarrow::FloatArray::<f64>::from_slice(&[1.0, -2.0, 0.0]))
59 as Arc<minarrow::FloatArray<f64>>;
60
61 let arr_bool = Arc::new(minarrow::BooleanArray::<()>::from_slice(&[
62 true, false, true,
63 ])) as Arc<minarrow::BooleanArray<()>>;
64
65 let arr_string32 = Arc::new(minarrow::StringArray::<u32>::from_slice(&[
66 "abc", "def", "",
67 ])) as Arc<minarrow::StringArray<u32>>;
68 let arr_categorical32 = Arc::new(minarrow::CategoricalArray::<u32>::from_slices(
69 &[0, 1, 2],
70 &["A".to_string(), "B".to_string(), "C".to_string()],
71 )) as Arc<minarrow::CategoricalArray<u32>>;
72
73 #[cfg(feature = "datetime")]
74 let arr_datetime32 = Arc::new(minarrow::DatetimeArray::<i32> {
75 data: minarrow::Buffer::<i32>::from_slice(&[
76 1_600_000_000 / 86_400,
77 1_600_000_001 / 86_400,
78 1_600_000_002 / 86_400,
79 ]),
80 null_mask: None,
81 time_unit: TimeUnit::Days,
82 });
83 #[cfg(feature = "datetime")]
84 let arr_datetime64 = Arc::new(minarrow::DatetimeArray::<i64> {
85 data: minarrow::Buffer::<i64>::from_slice(&[
86 1_600_000_000_000,
87 1_600_000_000_001,
88 1_600_000_000_002,
89 ]),
90 null_mask: None,
91 time_unit: TimeUnit::Milliseconds,
92 }) as Arc<_>;
93
94 // ---- 2. Wrap into Array enums ----
95 #[cfg(feature = "extended_numeric_types")]
96 let minarr_int8 = Array::NumericArray(NumericArray::Int8(arr_int8));
97 #[cfg(feature = "extended_numeric_types")]
98 let minarr_int16 = Array::NumericArray(NumericArray::Int16(arr_int16));
99 let minarr_int32 = Array::NumericArray(NumericArray::Int32(arr_int32));
100 let minarr_int64 = Array::NumericArray(NumericArray::Int64(arr_int64));
101 #[cfg(feature = "extended_numeric_types")]
102 let minarr_uint8 = Array::NumericArray(NumericArray::UInt8(arr_uint8));
103 #[cfg(feature = "extended_numeric_types")]
104 let minarr_uint16 = Array::NumericArray(NumericArray::UInt16(arr_uint16));
105 let minarr_uint32 = Array::NumericArray(NumericArray::UInt32(arr_uint32));
106 let minarr_uint64 = Array::NumericArray(NumericArray::UInt64(arr_uint64));
107 let minarr_float32 = Array::NumericArray(NumericArray::Float32(arr_float32));
108 let minarr_float64 = Array::NumericArray(NumericArray::Float64(arr_float64));
109 let minarr_bool = Array::BooleanArray(arr_bool);
110 let minarr_string32 = Array::TextArray(TextArray::String32(arr_string32));
111 let minarr_categorical32 = Array::TextArray(TextArray::Categorical32(arr_categorical32));
112 #[cfg(feature = "datetime")]
113 let minarr_datetime32 = Array::TemporalArray(TemporalArray::Datetime32(arr_datetime32));
114 #[cfg(feature = "datetime")]
115 let minarr_datetime64 = Array::TemporalArray(TemporalArray::Datetime64(arr_datetime64));
116
117 // ---- 3. Build Fields with correct logical types ----
118 #[cfg(feature = "extended_numeric_types")]
119 let field_int8 = Field::new("int8", ArrowType::Int8, false, None);
120 #[cfg(feature = "extended_numeric_types")]
121 let field_int16 = Field::new("int16", ArrowType::Int16, false, None);
122 let field_int32 = Field::new("int32", ArrowType::Int32, false, None);
123 let field_int64 = Field::new("int64", ArrowType::Int64, false, None);
124 #[cfg(feature = "extended_numeric_types")]
125 let field_uint8 = Field::new("uint8", ArrowType::UInt8, false, None);
126 #[cfg(feature = "extended_numeric_types")]
127 let field_uint16 = Field::new("uint16", ArrowType::UInt16, false, None);
128 let field_uint32 = Field::new("uint32", ArrowType::UInt32, false, None);
129 let field_uint64 = Field::new("uint64", ArrowType::UInt64, false, None);
130 let field_float32 = Field::new("float32", ArrowType::Float32, false, None);
131 let field_float64 = Field::new("float64", ArrowType::Float64, false, None);
132 let field_bool = Field::new("bool", ArrowType::Boolean, false, None);
133 let field_string32 = Field::new("string32", ArrowType::String, false, None);
134 let field_categorical32 = Field::new(
135 "categorical32",
136 ArrowType::Dictionary(CategoricalIndexType::UInt32),
137 false,
138 None,
139 );
140
141 #[cfg(feature = "datetime")]
142 let field_datetime32 = Field::new("dt32", ArrowType::Date32, false, None);
143 #[cfg(feature = "datetime")]
144 let field_datetime64 = Field::new("dt64", ArrowType::Date64, false, None);
145
146 // ---- 4. Build FieldArrays ----
147 #[cfg(feature = "extended_numeric_types")]
148 let fa_int8 = FieldArray::new(field_int8, minarr_int8);
149 #[cfg(feature = "extended_numeric_types")]
150 let fa_int16 = FieldArray::new(field_int16, minarr_int16);
151 let fa_int32 = FieldArray::new(field_int32, minarr_int32);
152 let fa_int64 = FieldArray::new(field_int64, minarr_int64);
153 #[cfg(feature = "extended_numeric_types")]
154 let fa_uint8 = FieldArray::new(field_uint8, minarr_uint8);
155 #[cfg(feature = "extended_numeric_types")]
156 let fa_uint16 = FieldArray::new(field_uint16, minarr_uint16);
157 let fa_uint32 = FieldArray::new(field_uint32, minarr_uint32);
158 let fa_uint64 = FieldArray::new(field_uint64, minarr_uint64);
159 let fa_float32 = FieldArray::new(field_float32, minarr_float32);
160 let fa_float64 = FieldArray::new(field_float64, minarr_float64);
161 let fa_bool = FieldArray::new(field_bool, minarr_bool);
162 let fa_string32 = FieldArray::new(field_string32, minarr_string32);
163 let fa_categorical32 = FieldArray::new(field_categorical32, minarr_categorical32);
164 #[cfg(feature = "datetime")]
165 let fa_datetime32 = FieldArray::new(field_datetime32, minarr_datetime32);
166 #[cfg(feature = "datetime")]
167 let fa_datetime64 = FieldArray::new(field_datetime64, minarr_datetime64);
168
169 // ---- 5. Build Table ----
170 let mut cols = Vec::new();
171 #[cfg(feature = "extended_numeric_types")]
172 {
173 cols.push(fa_int8);
174 cols.push(fa_int16);
175 }
176 cols.push(fa_int32);
177 cols.push(fa_int64);
178 #[cfg(feature = "extended_numeric_types")]
179 {
180 cols.push(fa_uint8);
181 cols.push(fa_uint16);
182 }
183 cols.push(fa_uint32);
184 cols.push(fa_uint64);
185 cols.push(fa_float32);
186 cols.push(fa_float64);
187 cols.push(fa_bool);
188 cols.push(fa_string32);
189 cols.push(fa_categorical32);
190 #[cfg(feature = "datetime")]
191 {
192 cols.push(fa_datetime32);
193 cols.push(fa_datetime64);
194 }
195 let minarrow_table = Table::new("ffi_test".to_string(), Some(cols));
196
197 // ---- 6. Export each column over FFI, import into Arrow-RS, and roundtrip back to Minarrow ----
198 for (_, col) in minarrow_table.cols.iter().enumerate() {
199 let array_arc = Arc::new(col.array.clone());
200 let schema = Schema::from(vec![(*col.field).clone()]);
201
202 // println!("Minarrow Pre-roundtrip for '{:?}':\n{:#?}", *col.field, array_arc);
203
204 let (c_arr, c_schema) = export_to_c(array_arc.clone(), schema);
205
206 // SAFETY: Arrow-RS expects raw pointers to FFI_ArrowArray/Schema
207 let arr_ptr = c_arr as *mut FFI_ArrowArray;
208 let schema_ptr = c_schema as *mut FFI_ArrowSchema;
209 let arrow_array = unsafe { arr_ptr.read() };
210 let arrow_schema = unsafe { schema_ptr.read() };
211 let array_data = unsafe { arrow_from_ffi(arrow_array, &arrow_schema) }
212 .expect("Arrow FFI import failed");
213 let field_name = &col.field.name;
214 println!(
215 "Imported field '{}' as Arrow type {:?}",
216 field_name,
217 array_data.data_type()
218 );
219 println!("Arrow-RS values for '{}':", field_name);
220 println!(" {:?}", array_data);
221
222 // Convert ArrayData to ArrayRef
223 let array_ref: ArrayRef = make_array(array_data.clone());
224
225 // Pretty print as a table
226 let arrow_schema = Arc::new(arrow::datatypes::Schema::new(vec![
227 arrow::datatypes::Field::new(field_name, array_ref.data_type().clone(), false),
228 ]));
229 let batch = RecordBatch::try_new(arrow_schema, vec![array_ref.clone()]).unwrap();
230 println!("Arrow-RS pretty-print for '{}':", field_name);
231 arrow::util::pretty::print_batches(&[batch]).unwrap();
232
233 // ---- 7. Export Arrow-RS back to Minarrow FFI, roundtrip ----
234 let (ffi_out_arr, ffi_out_schema) =
235 arrow_to_ffi(&array_data).expect("Arrow to FFI failed");
236
237 // Correctly allocate Arrow-RS FFI structs on the heap and cast as raw pointers to your C ABI structs
238 let ffi_out_arr_box = Box::new(ffi_out_arr);
239 let ffi_out_schema_box = Box::new(ffi_out_schema);
240
241 let arr_ptr =
242 Box::into_raw(ffi_out_arr_box) as *const minarrow::ffi::arrow_c_ffi::ArrowArray;
243 let schema_ptr =
244 Box::into_raw(ffi_out_schema_box) as *const minarrow::ffi::arrow_c_ffi::ArrowSchema;
245
246 // Now import back into minarrow using your real FFI import
247 let minarr_back_array: Arc<Array> = unsafe { import_from_c(arr_ptr, schema_ptr) };
248
249 println!(
250 "Minarrow array (roundtrip) for '{}':\n{:#?}",
251 field_name, minarr_back_array
252 );
253
254 // ---- 8. Validate roundtrip equality ----
255 assert_eq!(
256 &col.array,
257 minarr_back_array.as_ref(),
258 "Roundtrip array does not match for field {}",
259 field_name
260 );
261 }
262
263 println!("FFI roundtrip test completed for all supported types.");
264 }Sourcepub fn add_col(&mut self, field_array: FieldArray)
pub fn add_col(&mut self, field_array: FieldArray)
Adds a column with a name.
Examples found in repository?
280fn test_table_broadcasting() {
281 println!("┌─ Test 9: Table Broadcasting");
282 println!(
283 "│ Operation: Table{{col1:[1,2,3], col2:[4,5,6]}} + Table{{col1:[10,10,10], col2:[20,20,20]}}"
284 );
285 println!("│ Expected: Table{{col1:[11,12,13], col2:[24,25,26]}}");
286
287 // Create first table with two columns
288 let arr1_col1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2, 3]));
289 let arr1_col2 = Array::from_int32(IntegerArray::from_slice(&vec64![4, 5, 6]));
290 let fa1_col1 = minarrow::FieldArray::from_arr("col1", arr1_col1);
291 let fa1_col2 = minarrow::FieldArray::from_arr("col2", arr1_col2);
292 let mut table1 = Table::new("table1".to_string(), None);
293 table1.add_col(fa1_col1);
294 table1.add_col(fa1_col2);
295
296 // Create second table with matching structure
297 let arr2_col1 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10, 10]));
298 let arr2_col2 = Array::from_int32(IntegerArray::from_slice(&vec64![20, 20, 20]));
299 let fa2_col1 = minarrow::FieldArray::from_arr("col1", arr2_col1);
300 let fa2_col2 = minarrow::FieldArray::from_arr("col2", arr2_col2);
301 let mut table2 = Table::new("table2".to_string(), None);
302 table2.add_col(fa2_col1);
303 table2.add_col(fa2_col2);
304
305 match Value::Table(Arc::new(table1)) + Value::Table(Arc::new(table2)) {
306 Ok(Value::Table(result)) => {
307 if let Array::NumericArray(NumericArray::Int32(col1)) = &result.cols[0].array {
308 println!("│ Result col1: {:?}", col1.data.as_slice());
309 }
310 if let Array::NumericArray(NumericArray::Int32(col2)) = &result.cols[1].array {
311 println!("│ Result col2: {:?}", col2.data.as_slice());
312 }
313 println!("└─ ✓ Passed\n");
314 }
315 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
316 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
317 }
318}
319
320/// Test ArrayView broadcasting - efficient windowed operations
321fn test_array_view_broadcasting() {
322 #[cfg(feature = "views")]
323 {
324 println!("┌─ Test 10: ArrayView Broadcasting");
325 println!("│ Operation: ArrayView([2,3,4]) + ArrayView([10,10,10])");
326 println!("│ Expected: Array([12,13,14])");
327
328 // Create an array and a view into it
329 let arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2, 3, 4, 5]));
330 let view1 = ArrayV::new(arr1, 1, 3); // View of elements [2,3,4]
331
332 let arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10, 10]));
333 let view2 = ArrayV::new(arr2, 0, 3);
334
335 match Value::ArrayView(Arc::new(view1)) + Value::ArrayView(Arc::new(view2)) {
336 Ok(Value::Array(arr_arc)) => {
337 if let Array::NumericArray(NumericArray::Int32(result)) = arr_arc.as_ref() {
338 println!("│ Result: {:?}", result.data.as_slice());
339 println!("└─ ✓ Passed\n");
340 } else {
341 println!("└─ ✗ Error: Unexpected array type\n");
342 }
343 }
344 Ok(_) => println!("└─ ✗ Error: Unexpected result type\n"),
345 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
346 }
347 }
348
349 #[cfg(not(feature = "views"))]
350 {
351 println!("┌─ Test 10: ArrayView Broadcasting");
352 println!("└─ ⊘ Skipped (views feature not enabled)\n");
353 }
354}
355
356/// Test SuperArray broadcasting - chunked array operations
357fn test_super_array_broadcasting() {
358 #[cfg(feature = "chunked")]
359 {
360 println!("┌─ Test 11: SuperArray (Chunked) Broadcasting");
361 println!("│ Operation: SuperArray{{[1,2],[3,4]}} * SuperArray{{[2,2],[2,2]}}");
362 println!("│ Expected: SuperArray{{[2,4],[6,8]}}");
363
364 // Create chunked arrays (multiple field array chunks)
365 let chunk1_a = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2]));
366 let chunk2_a = Array::from_int32(IntegerArray::from_slice(&vec64![3, 4]));
367 let fa1 = minarrow::FieldArray::from_arr("chunk1", chunk1_a);
368 let fa2 = minarrow::FieldArray::from_arr("chunk1", chunk2_a);
369 let super_arr1 = SuperArray::from_field_array_chunks(vec![fa1, fa2]);
370
371 let chunk1_b = Array::from_int32(IntegerArray::from_slice(&vec64![2, 2]));
372 let chunk2_b = Array::from_int32(IntegerArray::from_slice(&vec64![2, 2]));
373 let fa3 = minarrow::FieldArray::from_arr("chunk1", chunk1_b);
374 let fa4 = minarrow::FieldArray::from_arr("chunk1", chunk2_b);
375 let super_arr2 = SuperArray::from_field_array_chunks(vec![fa3, fa4]);
376
377 match Value::SuperArray(Arc::new(super_arr1)) * Value::SuperArray(Arc::new(super_arr2)) {
378 Ok(Value::SuperArray(result)) => {
379 println!("│ Result with {} chunks:", result.len());
380 for i in 0..result.len() {
381 if let Some(fa) = result.chunk(i) {
382 if let Array::NumericArray(NumericArray::Int32(arr)) = &fa.array {
383 println!("│ Chunk {}: {:?}", i, arr.data.as_slice());
384 }
385 }
386 }
387 println!("└─ ✓ Passed\n");
388 }
389 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
390 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
391 }
392 }
393
394 #[cfg(not(feature = "chunked"))]
395 {
396 println!("┌─ Test 11: SuperArray (Chunked) Broadcasting");
397 println!("└─ ⊘ Skipped (chunked feature not enabled)\n");
398 }
399}
400
401/// Test Cube broadcasting - 3D tensor operations
402fn test_cube_broadcasting() {
403 #[cfg(feature = "cube")]
404 {
405 println!("┌─ Test 12: Cube (3D) Broadcasting");
406 println!("│ Operation: Cube{{2 tables}} + Cube{{2 tables}}");
407 println!("│ Expected: Element-wise addition across all tables");
408
409 // Create first cube with 2 tables
410 // First, create columns for table 1
411 let t1_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2]));
412 let t1_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![3, 4]));
413 let t1_fa1 = minarrow::FieldArray::from_arr("col1", t1_arr1);
414 let t1_fa2 = minarrow::FieldArray::from_arr("col2", t1_arr2);
415
416 // Create columns for cube1 via constructor
417 let mut cube1 = Cube::new("cube1".to_string(), Some(vec![t1_fa1, t1_fa2]), None);
418
419 // Add second table to cube1
420 let t2_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![5, 6]));
421 let t2_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![7, 8]));
422 let t2_fa1 = minarrow::FieldArray::from_arr("col1", t2_arr1);
423 let t2_fa2 = minarrow::FieldArray::from_arr("col2", t2_arr2);
424 let mut table2 = Table::new("t2".to_string(), None);
425 table2.add_col(t2_fa1);
426 table2.add_col(t2_fa2);
427 cube1.add_table(table2);
428
429 // Create second cube
430 let t3_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10]));
431 let t3_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![20, 20]));
432 let t3_fa1 = minarrow::FieldArray::from_arr("col1", t3_arr1);
433 let t3_fa2 = minarrow::FieldArray::from_arr("col2", t3_arr2);
434 let mut cube2 = Cube::new("cube2".to_string(), Some(vec![t3_fa1, t3_fa2]), None);
435
436 let t4_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![30, 30]));
437 let t4_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![40, 40]));
438 let t4_fa1 = minarrow::FieldArray::from_arr("col1", t4_arr1);
439 let t4_fa2 = minarrow::FieldArray::from_arr("col2", t4_arr2);
440 let mut table4 = Table::new("t4".to_string(), None);
441 table4.add_col(t4_fa1);
442 table4.add_col(t4_fa2);
443 cube2.add_table(table4);
444
445 match Value::Cube(Arc::new(cube1)) + Value::Cube(Arc::new(cube2)) {
446 Ok(Value::Cube(result)) => {
447 println!("│ Result cube with {} tables:", result.n_tables());
448 for i in 0..result.n_tables() {
449 println!("│ Table {}:", i);
450 if let Some(table) = result.table(i) {
451 for j in 0..table.n_cols() {
452 let col = &table.cols[j];
453 if let Array::NumericArray(NumericArray::Int32(arr)) = &col.array {
454 println!("│ Column {}: {:?}", j, arr.data.as_slice());
455 }
456 }
457 }
458 }
459 println!("└─ ✓ Passed\n");
460 }
461 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
462 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
463 }
464 }
465
466 #[cfg(not(feature = "cube"))]
467 {
468 println!("┌─ Test 12: Cube (3D) Broadcasting");
469 println!("└─ ⊘ Skipped (cube feature not enabled)\n");
470 }
471}More examples
13fn main() {
14 // Inner arrays
15
16 // Numeric
17 let col_i32 = IntArr::<i32>::from_slice(&[1, 2, 3, 4, 5]);
18 let col_u32 = IntArr::<u32>::from_slice(&[100, 200, 300, 400, 500]);
19 let col_i64 = IntArr::<i64>::from_slice(&[10, 20, 30, 40, 50]);
20 let col_u64 = IntArr::<u64>::from_slice(&[101, 201, 301, 401, 501]);
21 let col_f32 = FltArr::<f32>::from_slice(&[1.1, 2.2, 3.3, 4.4, 5.5]);
22 let col_f64 = FltArr::<f64>::from_slice(&[2.2, 3.3, 4.4, 5.5, 6.6]);
23
24 // Boolean with nulls
25 let mut col_bool = BoolArr::from_slice(&[true, false, true, false, true]);
26 col_bool.set_null_mask(Some(Bitmask::from_bools(&[true, true, true, false, true])));
27
28 // String and Dictionary/Categorical
29 let col_str32 = StrArr::<u32>::from_slice(&["red", "blue", "green", "yellow", "purple"]);
30 let col_cat32 = CatArr::<u32>::from_values(
31 ["apple", "banana", "cherry", "banana", "apple"]
32 .iter()
33 .copied(),
34 );
35
36 // Datetime
37 #[cfg(feature = "datetime")]
38 let col_dt32 = DatetimeArray::<i32>::from_slice(
39 &[1000, 2000, 3000, 4000, 5000],
40 Some(TimeUnit::Milliseconds),
41 );
42 #[cfg(feature = "datetime")]
43 let col_dt64 = DatetimeArray::<i64>::from_slice(
44 &[
45 1_000_000_000,
46 2_000_000_000,
47 3_000_000_000,
48 4_000_000_000,
49 5_000_000_000,
50 ],
51 Some(TimeUnit::Nanoseconds),
52 );
53
54 // FieldArray (column) construction
55 let fa_i32 = FieldArray::from_arr("int32_col", col_i32);
56 let fa_u32 = FieldArray::from_arr("uint32_col", col_u32);
57 let fa_i64 = FieldArray::from_arr("int64_col", col_i64);
58 let fa_u64 = FieldArray::from_arr("uint64_col", col_u64);
59 let fa_f32 = FieldArray::from_arr("float32_col", col_f32);
60 let fa_f64 = FieldArray::from_arr("float64_col", col_f64);
61 let fa_bool = FieldArray::from_arr("bool_col", col_bool);
62 let fa_str32 = FieldArray::from_arr("utf8_col", col_str32);
63 let fa_cat32 = FieldArray::from_arr("dict32_col", col_cat32);
64 #[cfg(feature = "datetime")]
65 let fa_dt32 = FieldArray::from_arr("datetime32_col", col_dt32);
66 #[cfg(feature = "datetime")]
67 let fa_dt64 = FieldArray::from_arr("datetime64_col", col_dt64);
68
69 // Build Table
70 let mut tbl = Table::new("MyTable".to_string(), None);
71 tbl.add_col(fa_i32);
72 tbl.add_col(fa_u32);
73 tbl.add_col(fa_i64);
74 tbl.add_col(fa_u64);
75 tbl.add_col(fa_f32);
76 tbl.add_col(fa_f64);
77 tbl.add_col(fa_bool);
78 tbl.add_col(fa_str32);
79 tbl.add_col(fa_cat32);
80 #[cfg(feature = "datetime")]
81 tbl.add_col(fa_dt32);
82 #[cfg(feature = "datetime")]
83 tbl.add_col(fa_dt64);
84
85 // Print the table
86 tbl.print();
87}Sourcepub fn n_cols(&self) -> usize
pub fn n_cols(&self) -> usize
Returns the number of columns.
Examples found in repository?
402fn test_cube_broadcasting() {
403 #[cfg(feature = "cube")]
404 {
405 println!("┌─ Test 12: Cube (3D) Broadcasting");
406 println!("│ Operation: Cube{{2 tables}} + Cube{{2 tables}}");
407 println!("│ Expected: Element-wise addition across all tables");
408
409 // Create first cube with 2 tables
410 // First, create columns for table 1
411 let t1_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![1, 2]));
412 let t1_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![3, 4]));
413 let t1_fa1 = minarrow::FieldArray::from_arr("col1", t1_arr1);
414 let t1_fa2 = minarrow::FieldArray::from_arr("col2", t1_arr2);
415
416 // Create columns for cube1 via constructor
417 let mut cube1 = Cube::new("cube1".to_string(), Some(vec![t1_fa1, t1_fa2]), None);
418
419 // Add second table to cube1
420 let t2_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![5, 6]));
421 let t2_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![7, 8]));
422 let t2_fa1 = minarrow::FieldArray::from_arr("col1", t2_arr1);
423 let t2_fa2 = minarrow::FieldArray::from_arr("col2", t2_arr2);
424 let mut table2 = Table::new("t2".to_string(), None);
425 table2.add_col(t2_fa1);
426 table2.add_col(t2_fa2);
427 cube1.add_table(table2);
428
429 // Create second cube
430 let t3_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![10, 10]));
431 let t3_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![20, 20]));
432 let t3_fa1 = minarrow::FieldArray::from_arr("col1", t3_arr1);
433 let t3_fa2 = minarrow::FieldArray::from_arr("col2", t3_arr2);
434 let mut cube2 = Cube::new("cube2".to_string(), Some(vec![t3_fa1, t3_fa2]), None);
435
436 let t4_arr1 = Array::from_int32(IntegerArray::from_slice(&vec64![30, 30]));
437 let t4_arr2 = Array::from_int32(IntegerArray::from_slice(&vec64![40, 40]));
438 let t4_fa1 = minarrow::FieldArray::from_arr("col1", t4_arr1);
439 let t4_fa2 = minarrow::FieldArray::from_arr("col2", t4_arr2);
440 let mut table4 = Table::new("t4".to_string(), None);
441 table4.add_col(t4_fa1);
442 table4.add_col(t4_fa2);
443 cube2.add_table(table4);
444
445 match Value::Cube(Arc::new(cube1)) + Value::Cube(Arc::new(cube2)) {
446 Ok(Value::Cube(result)) => {
447 println!("│ Result cube with {} tables:", result.n_tables());
448 for i in 0..result.n_tables() {
449 println!("│ Table {}:", i);
450 if let Some(table) = result.table(i) {
451 for j in 0..table.n_cols() {
452 let col = &table.cols[j];
453 if let Array::NumericArray(NumericArray::Int32(arr)) = &col.array {
454 println!("│ Column {}: {:?}", j, arr.data.as_slice());
455 }
456 }
457 }
458 }
459 println!("└─ ✓ Passed\n");
460 }
461 Ok(other) => println!("└─ ✗ Error: Unexpected result type {:?}\n", other),
462 Err(e) => println!("└─ ✗ Error: {:?}\n", e),
463 }
464 }
465
466 #[cfg(not(feature = "cube"))]
467 {
468 println!("┌─ Test 12: Cube (3D) Broadcasting");
469 println!("└─ ⊘ Skipped (cube feature not enabled)\n");
470 }
471}Sourcepub fn col(&self, idx: usize) -> Option<&FieldArray>
pub fn col(&self, idx: usize) -> Option<&FieldArray>
Returns a column by index.
Examples found in repository?
4fn main() {
5 // Create a sample table
6 let table = create_sample_table();
7
8 println!("Original table:");
9 println!("{}\n", table);
10
11 // Table-specific API
12 println!("=== Table-specific API ===\n");
13
14 println!("table.c(&[\"name\", \"age\"]).r(1..4)");
15 let view1 = table.c(&["name", "age"]).r(1..4);
16 println!("{}\n", view1);
17
18 println!("table.c(&[0, 2]).r(&[0, 2, 4])");
19 let view2 = table.c(&[0, 2]).r(&[0, 2, 4]);
20 println!("{}\n", view2);
21
22 println!("table.c(0..2).r(0..5)");
23 let view3 = table.c(0..2).r(0..5);
24 println!("{}\n", view3);
25
26 println!("table.c(1).r(&[2, 4, 6])");
27 let view4 = table.c(1).r(&[2, 4, 6]);
28 println!("{}\n", view4);
29
30 // Aliased API
31 println!("=== Aliases ===\n");
32
33 println!("table.f(&[\"id\", \"age\"]).d(0..3)");
34 let view5 = table.f(&["id", "age"]).d(0..3);
35 println!("{}\n", view5);
36
37 println!("table.fields(&[\"name\"]).data(1..5)");
38 let view6 = table.fields(&["name"]).data(1..5);
39 println!("{}\n", view6);
40
41 println!("table.f(0..2).d(&[0, 3, 6, 9])");
42 let view7 = table.f(0..2).d(&[0, 3, 6, 9]);
43 println!("{}\n", view7);
44
45 println!("table.y(2).x(..5)");
46 let view8 = table.y(2).x(..5);
47 println!("{}\n", view8);
48
49 println!("table.fields(1..).data(5..)");
50 let view9 = table.fields(1..).data(5..);
51 println!("{}\n", view9);
52
53 // Materialise selections
54 println!("=== Materialisation ===\n");
55
56 println!("table.f(&[\"name\", \"age\"]).d(0..3).to_table()");
57 let view = table.f(&["name", "age"]).d(0..3);
58 let materialised = view.to_table();
59 println!("{}\n", materialised);
60
61 // Array and FieldArray selection
62 println!("=== Array & FieldArray Selection ===\n");
63
64 // Get a single column as FieldArray
65 let age_col = table.col(2).unwrap().clone();
66 println!("Original age column (FieldArray):");
67 println!(" Field: {} ({})", age_col.field.name, age_col.arrow_type());
68 println!(" Length: {}", age_col.len());
69 println!(" Values: {:?}\n", (0..age_col.len()).map(|i| age_col.array.inner::<IntegerArray<i32>>().get(i).unwrap()).collect::<Vec<_>>());
70
71 // Select specific rows from FieldArray using .d()
72 println!("age_col.d(&[1, 3, 5, 7])");
73 let age_view = age_col.d(&[1, 3, 5, 7]);
74 println!(" View length: {}", age_view.len());
75 println!(" Selected indices: {:?}\n", (0..age_view.len()).map(|i| age_view.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
76
77 // ArrayV selection (direct array view)
78 let id_array = Array::from_int32({
79 let mut arr = IntegerArray::<i32>::default();
80 for i in 0..10 {
81 arr.push(i * 10);
82 }
83 arr
84 });
85 let id_view = ArrayV::from(id_array);
86 println!("Original ArrayV:");
87 println!(" Length: {}", id_view.len());
88 println!(" Values: {:?}\n", (0..id_view.len()).map(|i| id_view.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
89
90 // Select from ArrayV using .data() and .x() aliases
91 println!("id_view.data(0..5)");
92 let id_selected1 = id_view.data(0..5);
93 println!(" Length: {}", id_selected1.len());
94 println!(" Values: {:?}\n", (0..id_selected1.len()).map(|i| id_selected1.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
95
96 println!("id_view.x(&[2, 4, 6, 8])");
97 let id_selected2 = id_view.x(&[2, 4, 6, 8]);
98 println!(" Length: {}", id_selected2.len());
99 println!(" Values: {:?}", (0..id_selected2.len()).map(|i| id_selected2.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
100}Sourcepub fn col_by_name(&self, name: &str) -> Option<&FieldArray>
pub fn col_by_name(&self, name: &str) -> Option<&FieldArray>
Returns a column by name.
Sourcepub fn remove_col(&mut self, name: &str) -> bool
pub fn remove_col(&mut self, name: &str) -> bool
Removes a column by name.
Sourcepub fn remove_col_at(&mut self, idx: usize) -> bool
pub fn remove_col_at(&mut self, idx: usize) -> bool
Removes a column by index.
Sourcepub fn cols(&self) -> &[FieldArray]
pub fn cols(&self) -> &[FieldArray]
Returns all columns.
Sourcepub fn cols_mut(&mut self) -> &mut [FieldArray]
pub fn cols_mut(&mut self) -> &mut [FieldArray]
Returns mutable reference to all columns.
pub fn iter(&self) -> Iter<'_, FieldArray>
pub fn iter_mut(&mut self) -> IterMut<'_, FieldArray>
pub fn set_name(&mut self, name: impl Into<String>)
Sourcepub fn slice_clone(&self, offset: usize, len: usize) -> Self
pub fn slice_clone(&self, offset: usize, len: usize) -> Self
Returns a new owned Table containing rows [offset, offset+len).
All columns are deeply copied, but only for the affected row(s).
Sourcepub fn slice(&self, offset: usize, len: usize) -> TableV
pub fn slice(&self, offset: usize, len: usize) -> TableV
Returns a zero-copy view over rows [offset, offset+len).
This view borrows from the parent table and does not copy data.
Sourcepub fn c<S: FieldSelector>(&self, selection: S) -> TableV
pub fn c<S: FieldSelector>(&self, selection: S) -> TableV
Select columns by names, indices, or ranges (table-specific convenience method).
This method delegates to .f() from the Selection trait.
For compatibility across dimensions, prefer using .f(), .fields(), or .y().
§Example
use minarrow::Table;
// Select columns by names
let view = table.c(&["A", "B", "C"]);
// Select columns by indices
let view = table.c(&[0, 1, 2]);
// Select columns by range
let view = table.c(0..3);
// Single column
let view = table.c("A");Examples found in repository?
4fn main() {
5 // Create a sample table
6 let table = create_sample_table();
7
8 println!("Original table:");
9 println!("{}\n", table);
10
11 // Table-specific API
12 println!("=== Table-specific API ===\n");
13
14 println!("table.c(&[\"name\", \"age\"]).r(1..4)");
15 let view1 = table.c(&["name", "age"]).r(1..4);
16 println!("{}\n", view1);
17
18 println!("table.c(&[0, 2]).r(&[0, 2, 4])");
19 let view2 = table.c(&[0, 2]).r(&[0, 2, 4]);
20 println!("{}\n", view2);
21
22 println!("table.c(0..2).r(0..5)");
23 let view3 = table.c(0..2).r(0..5);
24 println!("{}\n", view3);
25
26 println!("table.c(1).r(&[2, 4, 6])");
27 let view4 = table.c(1).r(&[2, 4, 6]);
28 println!("{}\n", view4);
29
30 // Aliased API
31 println!("=== Aliases ===\n");
32
33 println!("table.f(&[\"id\", \"age\"]).d(0..3)");
34 let view5 = table.f(&["id", "age"]).d(0..3);
35 println!("{}\n", view5);
36
37 println!("table.fields(&[\"name\"]).data(1..5)");
38 let view6 = table.fields(&["name"]).data(1..5);
39 println!("{}\n", view6);
40
41 println!("table.f(0..2).d(&[0, 3, 6, 9])");
42 let view7 = table.f(0..2).d(&[0, 3, 6, 9]);
43 println!("{}\n", view7);
44
45 println!("table.y(2).x(..5)");
46 let view8 = table.y(2).x(..5);
47 println!("{}\n", view8);
48
49 println!("table.fields(1..).data(5..)");
50 let view9 = table.fields(1..).data(5..);
51 println!("{}\n", view9);
52
53 // Materialise selections
54 println!("=== Materialisation ===\n");
55
56 println!("table.f(&[\"name\", \"age\"]).d(0..3).to_table()");
57 let view = table.f(&["name", "age"]).d(0..3);
58 let materialised = view.to_table();
59 println!("{}\n", materialised);
60
61 // Array and FieldArray selection
62 println!("=== Array & FieldArray Selection ===\n");
63
64 // Get a single column as FieldArray
65 let age_col = table.col(2).unwrap().clone();
66 println!("Original age column (FieldArray):");
67 println!(" Field: {} ({})", age_col.field.name, age_col.arrow_type());
68 println!(" Length: {}", age_col.len());
69 println!(" Values: {:?}\n", (0..age_col.len()).map(|i| age_col.array.inner::<IntegerArray<i32>>().get(i).unwrap()).collect::<Vec<_>>());
70
71 // Select specific rows from FieldArray using .d()
72 println!("age_col.d(&[1, 3, 5, 7])");
73 let age_view = age_col.d(&[1, 3, 5, 7]);
74 println!(" View length: {}", age_view.len());
75 println!(" Selected indices: {:?}\n", (0..age_view.len()).map(|i| age_view.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
76
77 // ArrayV selection (direct array view)
78 let id_array = Array::from_int32({
79 let mut arr = IntegerArray::<i32>::default();
80 for i in 0..10 {
81 arr.push(i * 10);
82 }
83 arr
84 });
85 let id_view = ArrayV::from(id_array);
86 println!("Original ArrayV:");
87 println!(" Length: {}", id_view.len());
88 println!(" Values: {:?}\n", (0..id_view.len()).map(|i| id_view.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
89
90 // Select from ArrayV using .data() and .x() aliases
91 println!("id_view.data(0..5)");
92 let id_selected1 = id_view.data(0..5);
93 println!(" Length: {}", id_selected1.len());
94 println!(" Values: {:?}\n", (0..id_selected1.len()).map(|i| id_selected1.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
95
96 println!("id_view.x(&[2, 4, 6, 8])");
97 let id_selected2 = id_view.x(&[2, 4, 6, 8]);
98 println!(" Length: {}", id_selected2.len());
99 println!(" Values: {:?}", (0..id_selected2.len()).map(|i| id_selected2.get::<IntegerArray<i32>>(i).unwrap()).collect::<Vec<_>>());
100}Sourcepub fn r<S: DataSelector>(&self, selection: S) -> TableV
pub fn r<S: DataSelector>(&self, selection: S) -> TableV
Select rows by indices or ranges (table-specific convenience method).
This method delegates to .d() from the Selection trait.
For compatibility across dimensions, prefer using .d(), .data(), or .x().
§Example
use minarrow::Table;
// Select rows by range
let view = table.r(10..20);
// Select specific rows
let view = table.r(&[1, 5, 10, 15]);
// Single row
let view = table.r(5);Sourcepub fn map_col<T, F>(&self, col_name: &str, func: F) -> Option<T>where
F: FnOnce(&FieldArray) -> T,
pub fn map_col<T, F>(&self, col_name: &str, func: F) -> Option<T>where
F: FnOnce(&FieldArray) -> T,
Maps a function over a single column by name, returning the result. Returns None if the column doesn’t exist.
Sourcepub fn map_cols_by_name<T, F>(&self, col_names: &[&str], func: F) -> Vec<T>where
F: FnMut(&FieldArray) -> T,
pub fn map_cols_by_name<T, F>(&self, col_names: &[&str], func: F) -> Vec<T>where
F: FnMut(&FieldArray) -> T,
Maps a function over multiple columns by name, returning a Vec of results. Warns if any requested columns are missing.
Sourcepub fn map_cols_by_index<T, F>(&self, indices: &[usize], func: F) -> Vec<T>where
F: FnMut(&FieldArray) -> T,
pub fn map_cols_by_index<T, F>(&self, indices: &[usize], func: F) -> Vec<T>where
F: FnMut(&FieldArray) -> T,
Maps a function over multiple columns by index, returning a Vec of results. Warns if any requested indices are out of bounds.
Sourcepub fn map_all_cols<T, F>(&self, func: F) -> Vec<T>where
F: FnMut(&FieldArray) -> T,
pub fn map_all_cols<T, F>(&self, func: F) -> Vec<T>where
F: FnMut(&FieldArray) -> T,
Maps a function over all columns, returning a Vec of results.
Source§impl Table
impl Table
pub fn par_iter(&self) -> Iter<'_, FieldArray>
pub fn par_iter_mut(&mut self) -> IterMut<'_, FieldArray>
Sourcepub fn to_apache_arrow(&self) -> RecordBatch
pub fn to_apache_arrow(&self) -> RecordBatch
Export each column to arrow-rs ArrayRef and build a RecordBatch.
The Arrow schema is derived from the imported array dtypes while preserving the original field names and nullability flags.
Trait Implementations§
Source§impl Concatenate for Table
impl Concatenate for Table
Source§fn concat(self, other: Self) -> Result<Self, MinarrowError>
fn concat(self, other: Self) -> Result<Self, MinarrowError>
Source§impl DataSelection for Table
Available on crate features views and select only.
impl DataSelection for Table
views and select only.Source§fn d<S: DataSelector>(&self, selection: S) -> TableV
fn d<S: DataSelector>(&self, selection: S) -> TableV
Source§fn get_data_count(&self) -> usize
fn get_data_count(&self) -> usize
Source§fn data<S: DataSelector>(&self, selection: S) -> Self::View
fn data<S: DataSelector>(&self, selection: S) -> Self::View
.d() - select dataSource§fn x<S: DataSelector>(&self, selection: S) -> Self::View
fn x<S: DataSelector>(&self, selection: S) -> Self::View
.d() - X-axis (horizontal, data dimension)Source§impl FieldSelection for Table
Available on crate features views and select only.
impl FieldSelection for Table
views and select only.Source§fn f<S: FieldSelector>(&self, selection: S) -> TableV
fn f<S: FieldSelector>(&self, selection: S) -> TableV
Source§fn fields<S: FieldSelector>(&self, selection: S) -> Self::View
fn fields<S: FieldSelector>(&self, selection: S) -> Self::View
.f() - select fieldsSource§fn y<S: FieldSelector>(&self, selection: S) -> Self::View
fn y<S: FieldSelector>(&self, selection: S) -> Self::View
.f() - Y-axis (vertical, schema dimension)Source§impl FromIterator<Table> for SuperTable
impl FromIterator<Table> for SuperTable
Source§impl<'a> IntoIterator for &'a Table
impl<'a> IntoIterator for &'a Table
Source§impl<'a> IntoIterator for &'a mut Table
impl<'a> IntoIterator for &'a mut Table
Source§impl IntoIterator for Table
impl IntoIterator for Table
Source§impl Shape for Table
impl Shape for Table
impl StructuralPartialEq for Table
Auto Trait Implementations§
impl Freeze for Table
impl RefUnwindSafe for Table
impl Send for Table
impl Sync for Table
impl Unpin for Table
impl UnwindSafe for Table
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> CustomValue for T
impl<T> CustomValue for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<I> IntoStreamingIterator for Iwhere
I: IntoIterator,
impl<I> IntoStreamingIterator for Iwhere
I: IntoIterator,
Source§fn into_streaming_iter(self) -> Convert<Self::IntoIter>
fn into_streaming_iter(self) -> Convert<Self::IntoIter>
Source§fn into_streaming_iter_ref<'a, T>(self) -> ConvertRef<'a, Self::IntoIter, T>
fn into_streaming_iter_ref<'a, T>(self) -> ConvertRef<'a, Self::IntoIter, T>
Source§fn into_streaming_iter_mut<'a, T>(self) -> ConvertMut<'a, Self::IntoIter, T>
fn into_streaming_iter_mut<'a, T>(self) -> ConvertMut<'a, Self::IntoIter, T>
Source§impl<T> Key for Twhere
T: Clone,
impl<T> Key for Twhere
T: Clone,
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read moreSource§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.