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