Skip to content

Commit 4965034

Browse files
authored
derive: add support for field attribute reference (#62)
1 parent d60090b commit 4965034

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ let result = client
7676
| `num_dim` | integer | Set this to a non-zero value to treat a field of type `float[]` as a vector field. |
7777
| `locale` | string | Locale for text processing |
7878
| `vec_dist` | string | Distance metric to be used for vector search |
79+
| `reference` | string | Name of a field in another collection to be used for JOINs |
7980
| `type` | string | Override the field type in Typesense |
8081
| `rename` | string | Rename the field in the Typesense schema |
8182
| `flatten` | -- | Generate Typesense field schemas for a nested struct |

typesense/tests/derive/collection.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ struct KitchenSinkProduct {
110110
// optional = false should override the Option<T> type
111111
#[typesense(optional = false)]
112112
optional_field: Option<i32>,
113+
114+
#[typesense(reference = "company.id")]
115+
company_id: String,
113116
}
114117

115118
#[test]
@@ -137,6 +140,7 @@ fn derived_document_handles_all_attributes() {
137140
{ "name": "btree_map_vec", "type": "object[]" },
138141

139142
{ "name": "optional_field", "type": "int32", "optional": false },
143+
{ "name": "company_id", "type": "string", "reference": "company.id" },
140144
],
141145
"default_sorting_field": "renamed_price",
142146
"token_separators": ["-", "/"],

typesense_derive/src/field_attributes.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub(crate) struct FieldAttributes {
2020
flatten: bool,
2121
pub(crate) rename: Option<String>,
2222
skip: bool,
23+
reference: Option<String>,
2324
}
2425

2526
// This function will parse #[typesense(...)] on a FIELD
@@ -209,6 +210,16 @@ pub(crate) fn extract_field_attrs(field: &Field) -> syn::Result<FieldAttributes>
209210
}
210211
res.vec_dist = Some(string_literal(&mut tt_iter)?);
211212
}
213+
"reference" => {
214+
skip_eq(&i, &mut tt_iter)?;
215+
if res.reference.is_some() {
216+
return Err(syn::Error::new_spanned(
217+
&i,
218+
"Attribute `reference` is duplicated",
219+
));
220+
}
221+
res.reference = Some(string_literal(&mut tt_iter)?);
222+
}
212223
"type" => {
213224
skip_eq(&i, &mut tt_iter)?;
214225
if res.type_override.is_some() {
@@ -283,12 +294,16 @@ fn build_regular_field(field: &Field, field_attrs: &FieldAttributes) -> proc_mac
283294
let range_index = field_attrs.range_index.map(|v| quote!(.range_index(#v)));
284295
let locale = field_attrs.locale.as_ref().map(|v| quote!(.locale(#v)));
285296
let vec_dist = field_attrs.vec_dist.as_ref().map(|v| quote!(.vec_dist(#v)));
297+
let reference = field_attrs
298+
.reference
299+
.as_ref()
300+
.map(|v| quote!(.reference(#v)));
286301
let num_dim = field_attrs.num_dim.map(|v| quote!(.num_dim(#v)));
287302

288303
quote! {
289304
vec![
290305
typesense::models::Field::builder().name(#field_name).r#type(#typesense_field_type)
291-
#optional #facet #index #store #sort #infix #stem #range_index #locale #vec_dist #num_dim
306+
#optional #facet #index #store #sort #infix #stem #range_index #locale #vec_dist #reference #num_dim
292307
.build()
293308
]
294309
}

0 commit comments

Comments
 (0)