apollo_utils/
submessages.rs1use std::str::FromStr;
2
3use core::fmt::Debug;
4use cosmwasm_std::{Event, StdError, StdResult, SubMsgResponse};
5
6pub fn parse_attribute_value<T: FromStr<Err = E>, E: Debug>(
8 event: &Event,
9 attr_key: &str,
10) -> StdResult<T> {
11 T::from_str(
12 event
13 .attributes
14 .iter()
15 .find(|attr| attr.key == attr_key)
16 .ok_or_else(|| {
17 StdError::generic_err(format!(
18 "Event {} event does not contain {} attribute",
19 event.ty, attr_key
20 ))
21 })?
22 .value
23 .as_str(),
24 )
25 .map_err(|e| {
26 StdError::generic_err(format!(
27 "Failed to parse attribute value from string. Error: {:?}",
28 e
29 ))
30 })
31}
32
33pub fn find_event<'a>(res: &'a SubMsgResponse, event_type: &str) -> StdResult<&'a Event> {
38 res.events
39 .iter()
40 .find(|event| event.ty == event_type)
41 .ok_or(StdError::generic_err(format!(
42 "No `{}` event found",
43 event_type
44 )))
45}
46
47#[cfg(test)]
48mod tests {
49 use std::num::ParseIntError;
50
51 use cosmwasm_std::Attribute;
52
53 use super::*;
54
55 #[test]
56 fn test_find_event_success() {
57 let event1 = Event::new("event_type_1");
58 let event2 = Event::new("event_type_2");
59 let events = vec![event1, event2];
60 let res = SubMsgResponse { events, data: None };
61 let result = find_event(&res, "event_type_1");
62 assert!(result.is_ok());
63 let found_event = result.unwrap();
64 assert_eq!(found_event.ty, "event_type_1");
65 }
66
67 #[test]
68 fn test_find_event_not_found() {
69 let event1 = Event::new("event_type_1");
70 let event2 = Event::new("event_type_2");
71 let events = vec![event1, event2];
72 let res = SubMsgResponse { events, data: None };
73 let result = find_event(&res, "event_type_3");
74 assert!(result.is_err());
75 let err = result.unwrap_err();
76 assert_eq!(
77 err.to_string(),
78 "Generic error: No `event_type_3` event found"
79 );
80 }
81
82 #[test]
83 fn test_parse_attribute_value_success() {
84 let attr1 = Attribute::new("key_1", "value_1");
85 let attr2 = Attribute::new("key_2", "2");
86 let attributes = vec![attr1, attr2];
87 let event = Event::new("event_type").add_attributes(attributes);
88
89 let result = parse_attribute_value::<i32, ParseIntError>(&event, "key_2");
90 assert!(result.is_ok());
91 let parsed_value = result.unwrap();
92 assert_eq!(parsed_value, 2);
93 }
94
95 #[test]
96 fn test_parse_attribute_value_not_found() {
97 let attr1 = Attribute::new("key_1", "value_1");
98 let attr2 = Attribute::new("key_2", "2");
99 let attributes = vec![attr1, attr2];
100 let event = Event::new("event_type").add_attributes(attributes);
101
102 let result = parse_attribute_value::<i32, ParseIntError>(&event, "key_3");
103 assert!(result.is_err());
104 let err = result.unwrap_err();
105 assert_eq!(
106 err.to_string(),
107 "Generic error: Event event_type event does not contain key_3 attribute"
108 );
109 }
110
111 #[test]
112 fn test_parse_attribute_value_parse_error() {
113 let attr1 = Attribute::new("key_1", "value_1");
114 let attr2 = Attribute::new("key_2", "not_a_number");
115 let attributes = vec![attr1, attr2];
116 let event = Event::new("event_type").add_attributes(attributes);
117
118 let result = parse_attribute_value::<i32, ParseIntError>(&event, "key_2");
119 assert!(result.is_err());
120 let err = result.unwrap_err();
121 assert_eq!(
122 err.to_string(),
123 "Generic error: Failed to parse attribute value from string. Error: ParseIntError { kind: InvalidDigit }"
124 );
125 }
126}