azure_functions/bindings/timer_info.rs
1use crate::{
2 rpc::{typed_data::Data, TypedData},
3 timer::ScheduleStatus,
4};
5use serde::Deserialize;
6use serde_json::from_str;
7use std::collections::HashMap;
8
9/// Represents the timer information from a timer trigger binding.
10///
11/// The following binding attributes are supported:
12///
13/// | Name | Description |
14/// |------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
15/// | `name` | The name of the parameter being bound. |
16/// | `schedule` | The CRON expression or a TimeSpan value for the timer. A TimeSpan can be used only for a function app that runs on an App Service Plan. |
17/// | `run_on_startup` | If `true`, the function is invoked when the runtime starts. It should rarely, if ever, be set to `true` in production as the function will be invoked on runtime restarts and scale outs. |
18/// | `use_monitor` | Set to `true` or `false` to indicate whether the schedule should be monitored. Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. |
19///
20/// # Examples
21///
22/// A function that runs every 5 minutes:
23///
24/// ```rust
25/// use azure_functions::bindings::TimerInfo;
26/// use azure_functions::func;
27/// use log::info;
28///
29/// #[func]
30/// #[binding(name = "_info", schedule = "0 */5 * * * *")]
31/// pub fn timer(_info: TimerInfo) {
32/// info!("Rust Azure function ran!");
33/// }
34/// ```
35#[derive(Debug, Deserialize)]
36#[serde(rename_all = "PascalCase")]
37pub struct TimerInfo {
38 /// The schedule status for the timer.
39 ///
40 /// If schedule monitoring is not enabled for the timer, this field will be `None`.
41 pub schedule_status: ScheduleStatus,
42 /// Determines if the timer invocation is due to a missed schedule occurrence.
43 pub is_past_due: bool,
44}
45
46impl TimerInfo {
47 #[doc(hidden)]
48 pub fn new(data: TypedData, _: HashMap<String, TypedData>) -> Self {
49 match &data.data {
50 Some(Data::Json(s)) => from_str(s).expect("failed to parse timer JSON data"),
51 _ => panic!("expected JSON data for timer trigger binding"),
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn it_has_json_data() {
62 const JSON: &'static str = r#"{"ScheduleStatus":{"Last":"0001-01-01T00:00:00","Next":"2018-07-24T23:24:00-07:00","LastUpdated":"0001-01-01T00:00:00"},"IsPastDue":true}"#;
63
64 let data = TypedData {
65 data: Some(Data::Json(JSON.to_string())),
66 };
67
68 let info = TimerInfo::new(data, HashMap::new());
69
70 assert!(info.is_past_due);
71
72 assert_eq!(
73 info.schedule_status.last.to_rfc3339(),
74 "0001-01-01T00:00:00+00:00"
75 );
76 assert_eq!(
77 info.schedule_status.next.to_rfc3339(),
78 "2018-07-25T06:24:00+00:00"
79 );
80 assert_eq!(
81 info.schedule_status.last_updated.to_rfc3339(),
82 "0001-01-01T00:00:00+00:00"
83 );
84 }
85}