Skip to main content

aws_lambda_events/event/lex/
mod.rs

1#[cfg(feature = "builders")]
2use bon::Builder;
3use serde::{Deserialize, Serialize};
4#[cfg(feature = "catch-all-fields")]
5use serde_json::Value;
6use std::collections::HashMap;
7
8use crate::custom_serde::deserialize_nullish;
9
10#[non_exhaustive]
11#[cfg_attr(feature = "builders", derive(Builder))]
12#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
13#[serde(rename_all = "camelCase")]
14pub struct LexEvent {
15    pub message_version: Option<String>,
16    pub invocation_source: Option<String>,
17    pub user_id: Option<String>,
18    pub input_transcript: Option<String>,
19    pub session_attributes: Option<SessionAttributes>,
20    #[serde(deserialize_with = "deserialize_nullish")]
21    #[serde(default)]
22    pub request_attributes: HashMap<String, String>,
23    pub bot: Option<LexBot>,
24    pub output_dialog_mode: Option<String>,
25    pub current_intent: Option<LexCurrentIntent>,
26    pub alternative_intents: Option<Vec<LexAlternativeIntents>>,
27    /// Deprecated: the DialogAction field is never populated by Lex events
28    pub dialog_action: Option<LexDialogAction>,
29    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
30    /// Enabled with Cargo feature `catch-all-fields`.
31    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
32    #[cfg(feature = "catch-all-fields")]
33    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
34    #[serde(flatten)]
35    #[cfg_attr(feature = "builders", builder(default))]
36    pub other: serde_json::Map<String, Value>,
37}
38
39#[non_exhaustive]
40#[cfg_attr(feature = "builders", derive(Builder))]
41#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
42#[serde(rename_all = "camelCase")]
43pub struct LexBot {
44    pub name: Option<String>,
45    pub alias: Option<String>,
46    pub version: Option<String>,
47    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
48    /// Enabled with Cargo feature `catch-all-fields`.
49    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
50    #[cfg(feature = "catch-all-fields")]
51    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
52    #[serde(flatten)]
53    #[cfg_attr(feature = "builders", builder(default))]
54    pub other: serde_json::Map<String, Value>,
55}
56
57#[non_exhaustive]
58#[cfg_attr(feature = "builders", derive(Builder))]
59#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
60#[serde(rename_all = "camelCase")]
61pub struct LexCurrentIntent {
62    pub name: Option<String>,
63    pub nlu_intent_confidence_score: Option<f64>,
64    pub slots: Option<Slots>,
65    #[serde(deserialize_with = "deserialize_nullish")]
66    #[serde(default)]
67    pub slot_details: HashMap<String, SlotDetail>,
68    pub confirmation_status: Option<String>,
69    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
70    /// Enabled with Cargo feature `catch-all-fields`.
71    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
72    #[cfg(feature = "catch-all-fields")]
73    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
74    #[serde(flatten)]
75    #[cfg_attr(feature = "builders", builder(default))]
76    pub other: serde_json::Map<String, Value>,
77}
78
79#[non_exhaustive]
80#[cfg_attr(feature = "builders", derive(Builder))]
81#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
82#[serde(rename_all = "camelCase")]
83pub struct LexAlternativeIntents {
84    pub name: Option<String>,
85    pub nlu_intent_confidence_score: Option<f64>,
86    pub slots: Option<Slots>,
87    #[serde(deserialize_with = "deserialize_nullish")]
88    #[serde(default)]
89    pub slot_details: HashMap<String, SlotDetail>,
90    pub confirmation_status: Option<String>,
91    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
92    /// Enabled with Cargo feature `catch-all-fields`.
93    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
94    #[cfg(feature = "catch-all-fields")]
95    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
96    #[serde(flatten)]
97    #[cfg_attr(feature = "builders", builder(default))]
98    pub other: serde_json::Map<String, Value>,
99}
100
101#[non_exhaustive]
102#[cfg_attr(feature = "builders", derive(Builder))]
103#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
104#[serde(rename_all = "camelCase")]
105pub struct SlotDetail {
106    pub resolutions: Option<Vec<HashMap<String, String>>>,
107    pub original_value: Option<String>,
108    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
109    /// Enabled with Cargo feature `catch-all-fields`.
110    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
111    #[cfg(feature = "catch-all-fields")]
112    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
113    #[serde(flatten)]
114    #[cfg_attr(feature = "builders", builder(default))]
115    pub other: serde_json::Map<String, Value>,
116}
117
118#[non_exhaustive]
119#[cfg_attr(feature = "builders", derive(Builder))]
120#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct LexDialogAction {
123    pub type_: Option<String>,
124    pub fulfillment_state: Option<String>,
125    #[serde(deserialize_with = "deserialize_nullish")]
126    #[serde(default)]
127    pub message: HashMap<String, String>,
128    pub intent_name: Option<String>,
129    pub slots: Option<Slots>,
130    pub slot_to_elicit: Option<String>,
131    pub response_card: Option<LexResponseCard>,
132    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
133    /// Enabled with Cargo feature `catch-all-fields`.
134    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
135    #[cfg(feature = "catch-all-fields")]
136    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
137    #[serde(flatten)]
138    #[cfg_attr(feature = "builders", builder(default))]
139    pub other: serde_json::Map<String, Value>,
140}
141
142pub type SessionAttributes = HashMap<String, String>;
143
144pub type Slots = HashMap<String, Option<String>>;
145
146#[non_exhaustive]
147#[cfg_attr(feature = "builders", derive(Builder))]
148#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
149#[serde(rename_all = "camelCase")]
150pub struct LexResponse {
151    pub session_attributes: SessionAttributes,
152    pub dialog_action: Option<LexDialogAction>,
153    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
154    /// Enabled with Cargo feature `catch-all-fields`.
155    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
156    #[cfg(feature = "catch-all-fields")]
157    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
158    #[serde(flatten)]
159    #[cfg_attr(feature = "builders", builder(default))]
160    pub other: serde_json::Map<String, Value>,
161}
162
163#[non_exhaustive]
164#[cfg_attr(feature = "builders", derive(Builder))]
165#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
166#[serde(rename_all = "camelCase")]
167pub struct LexResponseCard {
168    pub version: Option<i64>,
169    pub content_type: Option<String>,
170    pub generic_attachments: Option<Vec<Attachment>>,
171    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
172    /// Enabled with Cargo feature `catch-all-fields`.
173    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
174    #[cfg(feature = "catch-all-fields")]
175    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
176    #[serde(flatten)]
177    #[cfg_attr(feature = "builders", builder(default))]
178    pub other: serde_json::Map<String, Value>,
179}
180
181#[non_exhaustive]
182#[cfg_attr(feature = "builders", derive(Builder))]
183#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
184#[serde(rename_all = "camelCase")]
185pub struct Attachment {
186    pub title: Option<String>,
187    pub sub_title: Option<String>,
188    pub image_url: Option<String>,
189    pub attachment_link_url: Option<String>,
190    pub buttons: Option<Vec<HashMap<String, String>>>,
191    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
192    /// Enabled with Cargo feature `catch-all-fields`.
193    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
194    #[cfg(feature = "catch-all-fields")]
195    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
196    #[serde(flatten)]
197    #[cfg_attr(feature = "builders", builder(default))]
198    pub other: serde_json::Map<String, Value>,
199}
200
201#[cfg(test)]
202mod test {
203    use super::*;
204
205    #[test]
206    #[cfg(feature = "lex")]
207    fn example_lex_event() {
208        let data = include_bytes!("../../fixtures/example-lex-event.json");
209        let parsed: LexEvent = serde_json::from_slice(data).unwrap();
210        let output: String = serde_json::to_string(&parsed).unwrap();
211        let reparsed: LexEvent = serde_json::from_slice(output.as_bytes()).unwrap();
212        assert_eq!(parsed, reparsed);
213    }
214
215    #[test]
216    #[cfg(feature = "lex")]
217    fn example_lex_response() {
218        let data = include_bytes!("../../fixtures/example-lex-response.json");
219        let parsed: LexEvent = serde_json::from_slice(data).unwrap();
220        let output: String = serde_json::to_string(&parsed).unwrap();
221        let reparsed: LexEvent = serde_json::from_slice(output.as_bytes()).unwrap();
222        assert_eq!(parsed, reparsed);
223    }
224}