lineark_sdk/
pagination.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Default, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase", default)]
11pub struct PageInfo {
12 pub has_next_page: bool,
13 pub end_cursor: Option<String>,
14 pub has_previous_page: Option<bool>,
15 pub start_cursor: Option<String>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(rename_all = "camelCase")]
21#[serde(bound(deserialize = "T: serde::de::DeserializeOwned"))]
22pub struct Connection<T> {
23 #[serde(default)]
24 pub nodes: Vec<T>,
25 #[serde(rename = "pageInfo", default)]
26 pub page_info: PageInfo,
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 #[test]
34 fn page_info_deserializes_camel_case() {
35 let json = r#"{
36 "hasNextPage": true,
37 "endCursor": "abc123",
38 "hasPreviousPage": false,
39 "startCursor": "xyz"
40 }"#;
41 let pi: PageInfo = serde_json::from_str(json).unwrap();
42 assert!(pi.has_next_page);
43 assert_eq!(pi.end_cursor, Some("abc123".to_string()));
44 assert_eq!(pi.has_previous_page, Some(false));
45 assert_eq!(pi.start_cursor, Some("xyz".to_string()));
46 }
47
48 #[test]
49 fn page_info_defaults() {
50 let json = r#"{}"#;
51 let pi: PageInfo = serde_json::from_str(json).unwrap();
52 assert!(!pi.has_next_page);
53 assert!(pi.end_cursor.is_none());
54 assert!(pi.has_previous_page.is_none());
55 assert!(pi.start_cursor.is_none());
56 }
57
58 #[test]
59 fn connection_deserializes_with_nodes() {
60 let json = r#"{
61 "nodes": [{"value": 1}, {"value": 2}],
62 "pageInfo": {"hasNextPage": true, "endCursor": "cur"}
63 }"#;
64 let conn: Connection<serde_json::Value> = serde_json::from_str(json).unwrap();
65 assert_eq!(conn.nodes.len(), 2);
66 assert!(conn.page_info.has_next_page);
67 assert_eq!(conn.page_info.end_cursor, Some("cur".to_string()));
68 }
69
70 #[test]
71 fn connection_deserializes_empty_nodes() {
72 let json = r#"{
73 "nodes": [],
74 "pageInfo": {"hasNextPage": false}
75 }"#;
76 let conn: Connection<serde_json::Value> = serde_json::from_str(json).unwrap();
77 assert!(conn.nodes.is_empty());
78 assert!(!conn.page_info.has_next_page);
79 }
80
81 #[test]
82 fn connection_defaults_when_missing() {
83 let json = r#"{}"#;
84 let conn: Connection<serde_json::Value> = serde_json::from_str(json).unwrap();
85 assert!(conn.nodes.is_empty());
86 assert!(!conn.page_info.has_next_page);
87 }
88
89 #[test]
90 fn page_info_serializes_camel_case() {
91 let pi = PageInfo {
92 has_next_page: true,
93 end_cursor: Some("abc".to_string()),
94 has_previous_page: Some(false),
95 start_cursor: None,
96 };
97 let json = serde_json::to_value(&pi).unwrap();
98 assert_eq!(json["hasNextPage"], true);
99 assert_eq!(json["endCursor"], "abc");
100 }
101}