abstract_sdk/cw_helpers/cosmwasm_std/
abstract_attributes.rs

1use abstract_std::ABSTRACT_EVENT_TYPE;
2use cosmwasm_std::{Attribute, Event, Response};
3
4/// Trait for adding `abstract` attributes to something
5pub trait AbstractAttributes {
6    /// Add the provided `attrs`
7    fn add_abstract_attributes<A: Into<Attribute>>(
8        self,
9        attrs: impl IntoIterator<Item = A>,
10    ) -> Self;
11}
12
13/// Trait for adding `abstract` events to a [`Response`]
14impl AbstractAttributes for Response {
15    fn add_abstract_attributes<A: Into<Attribute>>(
16        mut self,
17        attrs: impl IntoIterator<Item = A>,
18    ) -> Self {
19        // Find the index of the first abstract event in the events vector
20        let index = self.events.iter().position(|e| e.ty == ABSTRACT_EVENT_TYPE);
21
22        if let Some(index) = index {
23            // If an abstract event exists, replace it with a new event eq has the additional attributes
24            let event = self.events.remove(index);
25            let new_event = event.add_attributes(attrs);
26            self.events.insert(index, new_event);
27        } else {
28            // If an abstract event does not exist, create a new one with the additional attributes
29            let new_event = Event::new(ABSTRACT_EVENT_TYPE).add_attributes(attrs);
30            self.events.push(new_event);
31        }
32
33        self
34    }
35}
36
37#[cfg(test)]
38mod test {
39    #![allow(clippy::needless_borrows_for_generic_args)]
40    use super::*;
41
42    #[coverage_helper::test]
43    fn test_add_abstract_attributes_no_abstract_event() {
44        let mut response = Response::default();
45
46        assert!(response.events.is_empty());
47
48        response = response.add_abstract_attributes(vec![("key1", "value1")]);
49
50        assert_eq!(response.events.len(), 1);
51        let event = response.events.first().unwrap();
52        assert_eq!(event.ty, ABSTRACT_EVENT_TYPE.to_string());
53        assert_eq!(event.attributes.len(), 1);
54
55        let attr = event.attributes.first().unwrap();
56        assert_eq!(attr.key, "key1".to_string());
57        assert_eq!(attr.value, "value1".to_string());
58    }
59
60    #[coverage_helper::test]
61    fn test_add_abstract_attributes_with_abstract_event() {
62        const KEY_1: &str = "abstract_key1";
63        const VALUE_1: &str = "abstract_value1";
64        let mut response = Response::default()
65            .add_event(Event::new(ABSTRACT_EVENT_TYPE).add_attributes(vec![(KEY_1, VALUE_1)]));
66
67        assert_eq!(response.events.len(), 1);
68        let event = response.events.first().unwrap();
69        assert_eq!(event.ty, ABSTRACT_EVENT_TYPE.to_string());
70        assert_eq!(event.attributes.len(), 1);
71
72        // Add the attributes
73        const KEY_2: &str = "abstract_key2";
74        const VALUE_2: &str = "abstract_value2";
75        response = response.add_abstract_attributes(vec![(KEY_2, VALUE_2)]);
76
77        assert_eq!(response.events.len(), 1);
78        let event = response.events.first().unwrap();
79        assert_eq!(event.ty, ABSTRACT_EVENT_TYPE.to_string());
80        // should now be 2
81        assert_eq!(event.attributes.len(), 2);
82
83        let attr1 = event.attributes.first().unwrap();
84        assert_eq!(attr1.key, KEY_1.to_string());
85        assert_eq!(attr1.value, VALUE_1.to_string());
86
87        let attr2 = event.attributes.get(1).unwrap();
88        assert_eq!(attr2.key, KEY_2.to_string());
89        assert_eq!(attr2.value, VALUE_2.to_string());
90    }
91}