azure_functions_shared/codegen/bindings/
timer_trigger.rs

1use azure_functions_shared_codegen::binding;
2use std::borrow::Cow;
3
4#[binding(name = "timerTrigger", direction = "in")]
5pub struct TimerTrigger {
6    #[field(camel_case_value = true)]
7    pub name: Cow<'static, str>,
8    pub schedule: Cow<'static, str>,
9    #[field(name = "runOnStartup")]
10    pub run_on_startup: Option<bool>,
11    #[field(name = "useMonitor")]
12    pub use_monitor: Option<bool>,
13}
14
15#[cfg(test)]
16mod tests {
17    use super::*;
18    use crate::codegen::tests::should_panic;
19    use proc_macro2::{Span, TokenStream};
20    use quote::ToTokens;
21    use serde_json::to_string;
22    use syn::{parse_str, NestedMeta};
23
24    #[test]
25    fn it_serializes_to_json() {
26        let binding = TimerTrigger {
27            name: Cow::from("foo"),
28            schedule: Cow::from("bar"),
29            run_on_startup: Some(true),
30            use_monitor: Some(false),
31        };
32
33        assert_eq!(
34            to_string(&binding).unwrap(),
35            r#"{"type":"timerTrigger","direction":"in","name":"foo","schedule":"bar","runOnStartup":true,"useMonitor":false}"#
36        );
37    }
38
39    #[test]
40    fn it_parses_attribute_arguments() {
41        let binding: TimerTrigger = (
42            vec![
43                parse_str::<NestedMeta>(r#"name = "foo""#).unwrap(),
44                parse_str::<NestedMeta>(r#"schedule = "bar""#).unwrap(),
45                parse_str::<NestedMeta>(r#"run_on_startup = true"#).unwrap(),
46                parse_str::<NestedMeta>(r#"use_monitor = false"#).unwrap(),
47            ],
48            Span::call_site(),
49        )
50            .into();
51
52        assert_eq!(binding.name.as_ref(), "foo");
53        assert_eq!(binding.schedule.as_ref(), "bar");
54        assert_eq!(binding.run_on_startup.unwrap(), true);
55        assert_eq!(binding.use_monitor.unwrap(), false);
56    }
57
58    #[test]
59    fn it_requires_the_name_attribute_argument() {
60        should_panic(
61            || {
62                let _: TimerTrigger = (vec![], Span::call_site()).into();
63            },
64            "the 'name' argument is required for this binding",
65        );
66    }
67
68    #[test]
69    fn it_requires_the_name_attribute_be_a_string() {
70        should_panic(
71            || {
72                let _: TimerTrigger = (
73                    vec![parse_str::<NestedMeta>(r#"name = false"#).unwrap()],
74                    Span::call_site(),
75                )
76                    .into();
77            },
78            "expected a literal string value for the 'name' argument",
79        );
80    }
81
82    #[test]
83    fn it_requires_the_schedule_attribute_argument() {
84        should_panic(
85            || {
86                let _: TimerTrigger = (
87                    vec![parse_str::<NestedMeta>(r#"name = "foo""#).unwrap()],
88                    Span::call_site(),
89                )
90                    .into();
91            },
92            "the 'schedule' argument is required for this binding",
93        );
94    }
95
96    #[test]
97    fn it_requires_the_schedule_attribute_be_a_string() {
98        should_panic(
99            || {
100                let _: TimerTrigger = (
101                    vec![parse_str::<NestedMeta>(r#"schedule = false"#).unwrap()],
102                    Span::call_site(),
103                )
104                    .into();
105            },
106            "expected a literal string value for the 'schedule' argument",
107        );
108    }
109
110    #[test]
111    fn it_requires_the_run_on_startup_attribute_be_a_bool() {
112        should_panic(
113            || {
114                let _: TimerTrigger = (
115                    vec![parse_str::<NestedMeta>(r#"run_on_startup = 1"#).unwrap()],
116                    Span::call_site(),
117                )
118                    .into();
119            },
120            "expected a literal boolean value for the 'run_on_startup' argument",
121        );
122    }
123
124    #[test]
125    fn it_requires_the_use_monitor_attribute_be_a_bool() {
126        should_panic(
127            || {
128                let _: TimerTrigger = (
129                    vec![parse_str::<NestedMeta>(r#"use_monitor = 1"#).unwrap()],
130                    Span::call_site(),
131                )
132                    .into();
133            },
134            "expected a literal boolean value for the 'use_monitor' argument",
135        );
136    }
137
138    #[test]
139    fn it_converts_to_tokens() {
140        let binding = TimerTrigger {
141            name: Cow::from("foo"),
142            schedule: Cow::from("bar"),
143            run_on_startup: Some(true),
144            use_monitor: Some(false),
145        };
146
147        let mut stream = TokenStream::new();
148        binding.to_tokens(&mut stream);
149        let mut tokens = stream.to_string();
150        tokens.retain(|c| c != ' ');
151
152        assert_eq!(
153            tokens,
154            r#"::azure_functions::codegen::bindings::TimerTrigger{name:::std::borrow::Cow::Borrowed("foo"),schedule:::std::borrow::Cow::Borrowed("bar"),run_on_startup:Some(true),use_monitor:Some(false),}"#
155        );
156    }
157}