Skip to content

Commit

Permalink
Add the auto_coalesce annotation when deriving DecodeRow
Browse files Browse the repository at this point in the history
  • Loading branch information
photino committed Jan 24, 2025
1 parent d72c7da commit de1d01c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 20 deletions.
8 changes: 4 additions & 4 deletions crates/zino-core/src/schedule/async_job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ impl AsyncJobScheduler {
}

/// Returns the duration till the next job is supposed to run.
pub fn time_till_next_job(&self) -> Option<Duration> {
pub fn time_till_next_job(&self) -> Duration {
if self.jobs.is_empty() {
Some(DEFAULT_TICK_INTERVAL)
DEFAULT_TICK_INTERVAL
} else {
let mut duration = Duration::ZERO;
let now = Local::now();
Expand All @@ -257,7 +257,7 @@ impl AsyncJobScheduler {
}
}
}
Some(duration)
duration
}
}

Expand Down Expand Up @@ -300,7 +300,7 @@ impl AsyncScheduler for AsyncJobScheduler {

#[inline]
fn time_till_next_job(&self) -> Option<Duration> {
self.time_till_next_job()
Some(self.time_till_next_job())
}

#[inline]
Expand Down
8 changes: 4 additions & 4 deletions crates/zino-core/src/schedule/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ impl JobScheduler {
}

/// Returns the duration till the next job is supposed to run.
pub fn time_till_next_job(&self) -> Option<Duration> {
pub fn time_till_next_job(&self) -> Duration {
if self.jobs.is_empty() {
Some(DEFAULT_TICK_INTERVAL)
DEFAULT_TICK_INTERVAL
} else {
let mut duration = Duration::ZERO;
let now = Local::now();
Expand All @@ -257,7 +257,7 @@ impl JobScheduler {
}
}
}
Some(duration)
duration
}
}

Expand Down Expand Up @@ -295,7 +295,7 @@ impl Scheduler for JobScheduler {

#[inline]
fn time_till_next_job(&self) -> Option<Duration> {
self.time_till_next_job()
Some(self.time_till_next_job())
}

#[inline]
Expand Down
5 changes: 5 additions & 0 deletions crates/zino-derive/docs/decode_row.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
Derives the [`DecodeRow`](zino_orm::DecodeRow) trait.

# Attributes on structs

- **`#[schema(auto_coalesce)]`**: The `auto_coalesce` annotation is used to
coalesce the default values of model fields when decoding a row in the database.

# Attributes on struct fields

- **`#[schema(ignore)]`**: The `ignore` annotation is used to skip a particular field
Expand Down
59 changes: 47 additions & 12 deletions crates/zino-derive/src/decode_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ pub(super) fn parse_token_stream(input: DeriveInput) -> TokenStream {
// Model name
let name = input.ident;

// Parsing struct attributes
let mut auto_coalesce = true;
for attr in input.attrs.iter() {
for (key, value) in parser::parse_schema_attr(attr).into_iter() {
if key == "auto_coalesce" && value.is_some_and(|v| v == "false") {
auto_coalesce = false;
}
}
}

// Parsing field attributes
let mut decode_model_fields = Vec::new();
for field in parser::parse_struct_fields(input.data) {
Expand All @@ -36,18 +46,28 @@ pub(super) fn parse_token_stream(input: DeriveInput) -> TokenStream {
});
} else if type_name == "Option<Uuid>" {
decode_model_fields.push(quote! {
model.#ident = zino_orm::decode_uuid(row, #name).ok().filter(|id| !id.is_nil());
let value = zino_orm::decode_uuid(row, #name)?;
model.#ident = (!value.is_nil()).then_some(value);
});
} else if type_name == "Decimal" {
decode_model_fields.push(quote! {
model.#ident = zino_orm::decode_decimal(row, #name)?;
});
} else if type_name == "Map" {
decode_model_fields.push(quote! {
if let Some(JsonValue::Object(map)) = zino_orm::decode_optional(row, #name)? {
model.#ident = map;
let field_decoder = if auto_coalesce {
quote! {
if let Some(JsonValue::Object(map)) = zino_orm::decode_optional(row, #name)? {
model.#ident = map;
}
}
});
} else {
quote! {
if let JsonValue::Object(map) = zino_orm::decode(row, #name)? {
model.#ident = map;
}
}
};
decode_model_fields.push(field_decoder);
} else if parser::check_option_type(&type_name) {
decode_model_fields.push(quote! {
model.#ident = zino_orm::decode_optional(row, #name)?;
Expand All @@ -58,17 +78,32 @@ pub(super) fn parse_token_stream(input: DeriveInput) -> TokenStream {
});
} else if UNSIGNED_INTEGER_TYPES.contains(&type_name.as_str()) {
let integer_type_ident = format_ident!("{}", type_name.replace('u', "i"));
decode_model_fields.push(quote! {
if let Some(value) = zino_orm::decode_optional::<#integer_type_ident>(row, #name)? {
let field_decoder = if auto_coalesce {
quote! {
if let Some(value) = zino_orm::decode_optional::<#integer_type_ident>(row, #name)? {
model.#ident = value.try_into()?;
}
}
} else {
quote! {
let value = zino_orm::decode::<#integer_type_ident>(row, #name)?;
model.#ident = value.try_into()?;
}
});
};
decode_model_fields.push(field_decoder);
} else {
decode_model_fields.push(quote! {
if let Some(value) = zino_orm::decode_optional(row, #name)? {
model.#ident = value;
let field_decoder = if auto_coalesce {
quote! {
if let Some(value) = zino_orm::decode_optional(row, #name)? {
model.#ident = value;
}
}
});
} else {
quote! {
model.#ident = zino_orm::decode(row, #name)?;
}
};
decode_model_fields.push(field_decoder);
}
}
}
Expand Down

0 comments on commit de1d01c

Please sign in to comment.