1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//! Doctests for ToSchema derive macro
/// ```
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithFields {
/// some_name: String,
/// }
/// ```
;
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct NoFields;
/// ```
;
/// ```
/// # use delta_kernel_derive::ToSchema;
/// # use std::collections::HashMap;
/// #[derive(ToSchema)]
/// pub struct WithAngleBracketPath {
/// map_field: HashMap<String, String>,
/// }
/// ```
;
/// ```
/// # use delta_kernel_derive::ToSchema;
/// # use std::collections::HashMap;
/// #[derive(ToSchema)]
/// pub struct WithAttributedField {
/// #[allow_null_container_values]
/// map_field: HashMap<String, String>,
/// }
/// ```
;
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithInvalidAttributeTarget {
/// #[allow_null_container_values]
/// some_name: String,
/// }
/// ```
;
/// Verify that `#[allow_null_container_values]` works on `Option<HashMap<_, _>>` fields.
/// This is needed for optional map fields like `Remove.partition_values` that can contain
/// null values.
/// ```
/// # use delta_kernel_derive::ToSchema;
/// # use std::collections::HashMap;
/// #[derive(ToSchema)]
/// pub struct WithOptionalAttributedField {
/// #[allow_null_container_values]
/// map_field: Option<HashMap<String, String>>,
/// }
/// ```
;
/// Verify that `#[allow_null_container_values]` fails on `Option<_>` fields that are not maps.
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithInvalidOptionalAttributeTarget {
/// #[allow_null_container_values]
/// some_name: Option<String>,
/// }
/// ```
;
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// # use syn::Token;
/// #[derive(ToSchema)]
/// pub struct WithInvalidFieldType {
/// token: Token![struct],
/// }
/// ```
;
/// Verify that `#[field_id]` / `#[nested_field_id]` on a list field produce the expected
/// `parquet.field.id` and `delta.columnMapping.nested.ids` metadata on the generated `StructField`.
/// ```
/// # use delta_kernel_derive::ToSchema;
/// # use delta_kernel::schema::{ToSchema, ColumnMetadataKey, MetadataValue};
/// #[derive(ToSchema)]
/// pub struct WithFieldIds {
/// #[field_id = 132]
/// #[nested_field_id = 133]
/// split_offsets: Option<Vec<i64>>,
/// }
/// let schema = WithFieldIds::to_schema();
/// let field = schema.field("splitOffsets").unwrap();
/// assert_eq!(
/// field.metadata.get(ColumnMetadataKey::ParquetFieldId.as_ref()),
/// Some(&MetadataValue::Number(132)),
/// );
/// let nested = field
/// .metadata
/// .get(ColumnMetadataKey::ColumnMappingNestedIds.as_ref())
/// .unwrap();
/// assert_eq!(nested.to_string(), r#"{"splitOffsets.element":133}"#);
/// ```
;
/// Verify that `#[nested_field_id]` is rejected on a non-list field.
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithNestedFieldIdOnScalar {
/// #[nested_field_id = 5]
/// some_name: String,
/// }
/// ```
;
/// Verify that an out-of-range `#[field_id]` (must be `1..=i32::MAX`) is rejected.
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithOutOfRangeFieldId {
/// #[field_id = 9223372036854775807]
/// some_name: String,
/// }
/// ```
;
/// Verify that a malformed `#[field_id]` shape (bare path, no value) is rejected.
/// ```compile_fail
/// # use delta_kernel_derive::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithMalformedFieldId {
/// #[field_id]
/// some_name: String,
/// }
/// ```
;
/// Verify that a `#[skip_schema]` field is excluded from the generated schema while its siblings
/// remain.
/// ```
/// # use delta_kernel_derive::ToSchema;
/// # use delta_kernel::schema::ToSchema;
/// #[derive(ToSchema)]
/// pub struct WithSkippedField {
/// #[skip_schema]
/// skipped: String,
/// kept: i32,
/// }
/// let schema = WithSkippedField::to_schema();
/// assert!(schema.field("kept").is_some());
/// assert!(schema.field("skipped").is_none());
/// ```
;