Skip to content

Commit 14b5d24

Browse files
chrono types support (#74)
* Add chrono feature and impl for additional types * Small adjustment to derive macro qualified serde path * Move chrono to workspace * Impl ToTypesenseField via T for Option/Vec * Impl ToTypesenseField for Vec in `impl_to_typesense_field!` * `impl_to_typesense_field!` allow type bound --------- Co-authored-by: RoDmitry <gh@rdmtr.com>
1 parent f6f16da commit 14b5d24

File tree

4 files changed

+49
-23
lines changed

4 files changed

+49
-23
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ typesense_derive = { path = "./typesense_derive", version = "0.3" }
2121
anyhow = "1"
2222
base64 = "0.22"
2323
bon = "3"
24+
chrono = "0.4"
2425
clap = { version = "4", features = ["derive"] }
2526
hmac = "0.12"
2627
indexmap = { version = "2", features = ["serde"] }

typesense/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ description = "Client for typesense"
99

1010
[features]
1111
default = ["derive"]
12+
chrono = ["dep:chrono"]
1213

1314
# Provide derive(Typesense) macro.
1415
derive = ["typesense_derive"]
@@ -22,6 +23,7 @@ typesense_derive = { workspace = true, optional = true }
2223
anyhow = { workspace = true }
2324
base64 = { workspace = true }
2425
bon = { workspace = true }
26+
chrono = { workspace = true, optional = true }
2527
hmac = { workspace = true }
2628
reqwest-retry = { workspace = true }
2729
serde = { workspace = true }

typesense/src/traits/field_type.rs

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub type FieldType = String;
66
/// Trait that should implement each type of a document, in order to properly serialize the
77
/// Collection Schema according to the Typesense reference.
88
pub trait ToTypesenseField {
9-
/// Static function that should implement the types of the typesense documents.
9+
/// Mapping of a Typesense type.
1010
fn to_typesense_type() -> &'static str;
1111
}
1212
/// Generic implementation for any type that is also a Typesense document.
@@ -25,22 +25,54 @@ impl<T: Document> ToTypesenseField for Vec<T> {
2525
}
2626
}
2727

28+
impl<T: ToTypesenseField> ToTypesenseField for Option<T> {
29+
#[inline(always)]
30+
fn to_typesense_type() -> &'static str {
31+
T::to_typesense_type()
32+
}
33+
}
34+
2835
/// macro used internally to add implementations of ToTypesenseField for several rust types.
2936
#[macro_export]
3037
macro_rules! impl_to_typesense_field (
31-
($for:ty, $typesense_variant:expr) => {
38+
($for:ty, $typesense_type:expr) => {
3239
impl $crate::prelude::ToTypesenseField for $for {
3340
#[inline(always)]
3441
fn to_typesense_type() -> &'static str {
35-
$typesense_variant
42+
$typesense_type
43+
}
44+
}
45+
impl $crate::prelude::ToTypesenseField for Vec<$for> {
46+
#[inline(always)]
47+
fn to_typesense_type() -> &'static str {
48+
concat!($typesense_type, "[]")
49+
}
50+
}
51+
impl $crate::prelude::ToTypesenseField for Vec<Option<$for>> {
52+
#[inline(always)]
53+
fn to_typesense_type() -> &'static str {
54+
concat!($typesense_type, "[]")
3655
}
3756
}
3857
};
39-
($for:ty, $typesense_variant:expr, $any:ident) => {
40-
impl<$any> $crate::prelude::ToTypesenseField for $for {
58+
59+
($for:ty, $typesense_type:expr, $any:ident $(: $any_bound:path)?) => {
60+
impl<$any $(: $any_bound)?> $crate::prelude::ToTypesenseField for $for {
61+
#[inline(always)]
62+
fn to_typesense_type() -> &'static str {
63+
$typesense_type
64+
}
65+
}
66+
impl<$any $(: $any_bound)?> $crate::prelude::ToTypesenseField for Vec<$for> {
4167
#[inline(always)]
4268
fn to_typesense_type() -> &'static str {
43-
$typesense_variant
69+
concat!($typesense_type, "[]")
70+
}
71+
}
72+
impl<$any $(: $any_bound)?> $crate::prelude::ToTypesenseField for Vec<Option<$for>> {
73+
#[inline(always)]
74+
fn to_typesense_type() -> &'static str {
75+
concat!($typesense_type, "[]")
4476
}
4577
}
4678
};
@@ -63,19 +95,10 @@ impl_to_typesense_field!(bool, "bool");
6395
impl_to_typesense_field!(HashMap<String, T>, "object", T);
6496
impl_to_typesense_field!(BTreeMap<String, T>, "object", T);
6597

66-
impl_to_typesense_field!(Vec<String>, "string[]");
67-
impl_to_typesense_field!(Vec<i8>, "int32[]");
68-
impl_to_typesense_field!(Vec<u8>, "int32[]");
69-
impl_to_typesense_field!(Vec<i16>, "int32[]");
70-
impl_to_typesense_field!(Vec<u16>, "int32[]");
71-
impl_to_typesense_field!(Vec<i32>, "int32[]");
72-
impl_to_typesense_field!(Vec<u32>, "int64[]");
73-
impl_to_typesense_field!(Vec<i64>, "int64[]");
74-
impl_to_typesense_field!(Vec<u64>, "int64[]");
75-
impl_to_typesense_field!(Vec<isize>, "int64[]");
76-
impl_to_typesense_field!(Vec<usize>, "int64[]");
77-
impl_to_typesense_field!(Vec<f32>, "float[]");
78-
impl_to_typesense_field!(Vec<f64>, "float[]");
79-
impl_to_typesense_field!(Vec<bool>, "bool[]");
80-
impl_to_typesense_field!(Vec<HashMap<String, T>>, "object[]", T);
81-
impl_to_typesense_field!(Vec<BTreeMap<String, T>>, "object[]", T);
98+
#[cfg(feature = "chrono")]
99+
mod chrono_support {
100+
impl_to_typesense_field!(chrono::DateTime<T>, "string", T: chrono::TimeZone);
101+
impl_to_typesense_field!(chrono::NaiveDate, "string");
102+
impl_to_typesense_field!(chrono::NaiveDateTime, "string");
103+
impl_to_typesense_field!(chrono::NaiveTime, "string");
104+
}

typesense_derive/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ fn impl_typesense_collection(item: ItemStruct) -> syn::Result<TokenStream> {
138138
let name_partial = Ident::new(&(ident.to_string() + "Partial"), ident.span());
139139

140140
let generated_code = quote! {
141-
#[derive(Default, Serialize)]
141+
#[derive(Default, ::serde::Serialize)]
142142
#vis struct #name_partial {
143143
#(#optional_fields)*
144144
}

0 commit comments

Comments
 (0)