aws_lambda_events/event/lex/
mod.rs1#[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 pub dialog_action: Option<LexDialogAction>,
29 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}