reifydb_core/encoded/shape/
from.rs1use reifydb_type::value::constraint::{Constraint, TypeConstraint};
5
6use crate::{
7 encoded::shape::{RowShape, RowShapeField},
8 interface::catalog::column::Column,
9};
10
11impl From<&Vec<Column>> for RowShape {
12 fn from(value: &Vec<Column>) -> Self {
13 RowShape::from(value.as_slice())
14 }
15}
16impl From<&[Column]> for RowShape {
17 fn from(value: &[Column]) -> Self {
18 let fields = value
19 .iter()
20 .map(|col| {
21 let constraint = match col.constraint.constraint() {
22 Some(Constraint::Dictionary(dict_id, id_type)) => {
23 TypeConstraint::dictionary(*dict_id, id_type.clone())
24 }
25 _ => col.constraint.clone(),
26 };
27 RowShapeField::new(col.name.clone(), constraint)
28 })
29 .collect();
30 RowShape::new(fields)
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 mod from_shape {
37 }
40
41 mod from_column {
42 use reifydb_type::value::{constraint::TypeConstraint, r#type::Type};
43
44 use crate::{
45 encoded::shape::{RowShape, RowShapeField},
46 interface::catalog::{
47 column::{Column, ColumnIndex},
48 id::ColumnId,
49 },
50 };
51
52 fn make_column(id: u64, name: &str, ty: Type, index: u8) -> Column {
53 Column {
54 id: ColumnId(id),
55 name: name.to_string(),
56 constraint: TypeConstraint::unconstrained(ty),
57 properties: vec![],
58 index: ColumnIndex(index),
59 auto_increment: false,
60 dictionary_id: None,
61 }
62 }
63
64 #[test]
65 fn test_from_column_single_field() {
66 let columns = vec![make_column(1, "id", Type::Int8, 0)];
67
68 let shape = RowShape::from(columns.as_slice());
69
70 assert_eq!(shape.fields().len(), 1);
71 assert_eq!(shape.fields()[0].name, "id");
72 assert_eq!(shape.fields()[0].constraint.get_type(), Type::Int8);
73 }
74
75 #[test]
76 fn test_from_column_multiple_fields() {
77 let columns = vec![
78 make_column(1, "a", Type::Int1, 0),
79 make_column(2, "b", Type::Int2, 1),
80 make_column(3, "c", Type::Int4, 2),
81 ];
82
83 let shape = RowShape::from(columns.as_slice());
84
85 assert_eq!(shape.fields().len(), 3);
86 assert_eq!(shape.fields()[0].name, "a");
87 assert_eq!(shape.fields()[0].constraint.get_type(), Type::Int1);
88 assert_eq!(shape.fields()[1].name, "b");
89 assert_eq!(shape.fields()[1].constraint.get_type(), Type::Int2);
90 assert_eq!(shape.fields()[2].name, "c");
91 assert_eq!(shape.fields()[2].constraint.get_type(), Type::Int4);
92 }
93
94 #[test]
95 fn test_from_column_preserves_field_order() {
96 let columns = vec![
97 make_column(1, "first", Type::Utf8, 0),
98 make_column(2, "second", Type::Int4, 1),
99 make_column(3, "third", Type::Boolean, 2),
100 ];
101
102 let shape = RowShape::from(columns.as_slice());
103
104 assert_eq!(shape.fields()[0].name, "first");
105 assert_eq!(shape.fields()[0].constraint.get_type(), Type::Utf8);
106 assert_eq!(shape.fields()[1].name, "second");
107 assert_eq!(shape.fields()[1].constraint.get_type(), Type::Int4);
108 assert_eq!(shape.fields()[2].name, "third");
109 assert_eq!(shape.fields()[2].constraint.get_type(), Type::Boolean);
110 }
111
112 #[test]
113 fn test_from_column_equivalence_with_direct_construction() {
114 let columns = vec![
115 make_column(1, "f0", Type::Uint1, 0),
116 make_column(2, "f1", Type::Uint2, 1),
117 make_column(3, "f2", Type::Uint4, 2),
118 make_column(4, "f3", Type::Uint8, 3),
119 make_column(5, "f4", Type::Uint16, 4),
120 ];
121
122 let shape_from_columns = RowShape::from(columns.as_slice());
123 let shape_direct = RowShape::new(vec![
124 RowShapeField::unconstrained("f0", Type::Uint1),
125 RowShapeField::unconstrained("f1", Type::Uint2),
126 RowShapeField::unconstrained("f2", Type::Uint4),
127 RowShapeField::unconstrained("f3", Type::Uint8),
128 RowShapeField::unconstrained("f4", Type::Uint16),
129 ]);
130
131 assert_eq!(shape_from_columns.fields().len(), shape_direct.fields().len());
133 assert_eq!(shape_from_columns.fingerprint(), shape_direct.fingerprint());
134
135 for (i, (from_columns, direct)) in
136 shape_from_columns.fields().iter().zip(shape_direct.fields().iter()).enumerate()
137 {
138 assert_eq!(from_columns.name, direct.name, "name mismatch at field {}", i);
139 assert_eq!(
140 from_columns.constraint, direct.constraint,
141 "constraint mismatch at field {}",
142 i
143 );
144 assert_eq!(from_columns.offset, direct.offset, "offset mismatch at field {}", i);
145 assert_eq!(from_columns.size, direct.size, "size mismatch at field {}", i);
146 assert_eq!(from_columns.align, direct.align, "align mismatch at field {}", i);
147 }
148 }
149
150 #[test]
151 fn test_from_column_empty() {
152 let columns: Vec<Column> = vec![];
153
154 let shape = RowShape::from(columns.as_slice());
155
156 assert_eq!(shape.fields().len(), 0);
157 }
158
159 #[test]
160 fn test_from_column_nine_fields() {
161 let columns = vec![
162 make_column(1, "f0", Type::Boolean, 0),
163 make_column(2, "f1", Type::Int1, 1),
164 make_column(3, "f2", Type::Int2, 2),
165 make_column(4, "f3", Type::Int4, 3),
166 make_column(5, "f4", Type::Int8, 4),
167 make_column(6, "f5", Type::Uint1, 5),
168 make_column(7, "f6", Type::Uint2, 6),
169 make_column(8, "f7", Type::Uint4, 7),
170 make_column(9, "f8", Type::Uint8, 8),
171 ];
172
173 let shape = RowShape::from(columns.as_slice());
174
175 assert_eq!(shape.fields().len(), 9);
176 for (i, field) in shape.fields().iter().enumerate() {
177 assert_eq!(field.name, format!("f{}", i));
178 }
179 }
180 }
181}