chainlink_data_streams_sdk/
feed.rs

1use chainlink_data_streams_report::feed_id::ID;
2
3use byteorder::{BigEndian, ByteOrder};
4use serde::{Deserialize, Serialize};
5
6/// Represents the feed report schema version.
7///
8/// The `FeedVersion` struct wraps a `u16` integer representing the version of the feed report schema.
9///
10/// # Examples
11///
12/// ```rust
13/// use chainlink_data_streams_sdk::feed::FeedVersion;
14///
15/// let version = FeedVersion(1);
16/// println!("Feed version: {}", version.0);
17/// ```
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub struct FeedVersion(pub u16);
20
21/// Represents a feed that identifies the report stream ID.
22///
23/// The `Feed` struct contains a `feed_id` field, which is an `ID` representing
24/// the unique identifier of the feed.
25///
26/// # Examples
27///
28/// ```rust
29/// use chainlink_data_streams_sdk::feed::Feed;
30/// use chainlink_data_streams_report::feed_id::ID;
31///
32/// let id = ID::from_hex_str("0x00016b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472").unwrap();
33/// let feed = Feed { feed_id: id };
34/// ```
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36pub struct Feed {
37    /// The unique identifier of the feed.
38    #[serde(rename = "feedID")]
39    pub feed_id: ID,
40}
41
42impl Feed {
43    /// Returns the feed version extracted from the first two bytes of the `ID`.
44    ///
45    /// # Returns
46    ///
47    /// A `FeedVersion` representing the version number.
48    ///
49    /// # Examples
50    ///
51    /// ```rust
52    /// use chainlink_data_streams_report::feed_id::ID;
53    /// use chainlink_data_streams_sdk::feed::{Feed, FeedVersion};
54    ///
55    /// let feed_id = ID::from_hex_str("0x00016b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472").unwrap();
56    /// let feed = Feed { feed_id };
57    /// let version = feed.version();
58    /// assert_eq!(version, FeedVersion(1));
59    /// ```
60    pub fn version(&self) -> FeedVersion {
61        let version = BigEndian::read_u16(&self.feed_id.0[0..2]);
62        FeedVersion(version)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    const V1_FEED_ID: ID = ID([
71        0, 1, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58,
72        163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114,
73    ]);
74    const V2_FEED_ID: ID = ID([
75        00, 02, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58,
76        163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114,
77    ]);
78    const V3_FEED_ID: ID = ID([
79        00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58,
80        163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114,
81    ]);
82    const V4_FEED_ID: ID = ID([
83        00, 04, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58,
84        163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114,
85    ]);
86
87    const V1_FEED_ID_STR: &str =
88        "0x00016b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472";
89    const V2_FEED_ID_STR: &str =
90        "0x00026b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472";
91    const V3_FEED_ID_STR: &str =
92        "0x00036b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472";
93    const V4_FEED_ID_STR: &str =
94        "0x00046b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472";
95
96    #[test]
97    fn test_feed_version() {
98        let feed_v1 = Feed {
99            feed_id: V1_FEED_ID,
100        };
101        let feed_v2 = Feed {
102            feed_id: V2_FEED_ID,
103        };
104        let feed_v3 = Feed {
105            feed_id: V3_FEED_ID,
106        };
107        let feed_v4 = Feed {
108            feed_id: V4_FEED_ID,
109        };
110
111        assert_eq!(feed_v1.version(), FeedVersion(1));
112        assert_eq!(feed_v2.version(), FeedVersion(2));
113        assert_eq!(feed_v3.version(), FeedVersion(3));
114        assert_eq!(feed_v4.version(), FeedVersion(4));
115    }
116
117    #[test]
118    fn test_serialize() {
119        let feeds = vec![
120            (V1_FEED_ID, V1_FEED_ID_STR),
121            (V2_FEED_ID, V2_FEED_ID_STR),
122            (V3_FEED_ID, V3_FEED_ID_STR),
123            (V4_FEED_ID, V4_FEED_ID_STR),
124        ];
125
126        for (feed_id, expected_str) in feeds {
127            let feed = Feed { feed_id };
128            let got = serde_json::to_string(&feed).unwrap();
129            let want = format!("{{\"feedID\":\"{}\"}}", expected_str);
130
131            assert_eq!(got, want);
132        }
133    }
134
135    #[test]
136    fn test_deserialize() {
137        let feeds = vec![
138            (V1_FEED_ID, V1_FEED_ID_STR),
139            (V2_FEED_ID, V2_FEED_ID_STR),
140            (V3_FEED_ID, V3_FEED_ID_STR),
141            (V4_FEED_ID, V4_FEED_ID_STR),
142        ];
143
144        for (feed_id, expected_str) in feeds {
145            let json = format!("{{\"feedID\":\"{}\"}}", expected_str);
146
147            let got: Feed = serde_json::from_str(&json).unwrap();
148            let want = Feed { feed_id };
149
150            assert_eq!(got, want);
151        }
152    }
153}