pinboard_rs/types/
v1.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
12pub struct Default {
13    pub result: String,
14}
15
16#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
17pub struct Note {
18    pub id: String,
19    pub hash: String,
20    pub title: String,
21    pub text: String,
22    pub length: usize,
23    pub created_at: String,
24    pub updated_at: String,
25}
26
27#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
28pub struct NoteSummary {
29    pub id: String,
30    pub hash: String,
31    pub title: String,
32    pub length: usize,
33    pub created_at: String,
34    pub updated_at: String,
35}
36
37#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
38pub struct NoteList {
39    pub count: usize,
40    pub notes: Vec<NoteSummary>,
41}
42
43#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
44pub struct Post {
45    pub href: String,
46    pub description: String,
47    pub extended: String,
48    pub meta: String,
49    pub hash: String,
50    pub time: DateTime<Utc>,
51    pub shared: String,
52    pub toread: String,
53    pub tags: String,
54}
55
56pub type Posts = Vec<Post>;
57
58#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
59pub struct PostsAdd {
60    pub result_code: String,
61}
62
63#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
64pub struct PostsDates {
65    pub user: String,
66    pub tag: String,
67    dates: HashMap<String, usize>,
68}
69
70#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
71pub struct PostsList {
72    pub tag: String,
73    pub user: String,
74    pub posts: Vec<Post>,
75}
76
77#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
78pub struct PostsRecent {
79    pub user: String,
80    pub date: DateTime<Utc>,
81    pub posts: Posts,
82}
83
84pub type PostsSubbest = Vec<std::collections::HashMap<String, Vec<String>>>;
85
86#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
87pub struct PostsUpdate {
88    pub update_time: DateTime<Utc>,
89}
90
91pub type Tags = HashMap<String, usize>;
92
93#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
94pub struct UserApiToken {
95    #[serde(rename = "result")]
96    pub token: String,
97}
98
99#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
100pub struct UserSecret {
101    #[serde(rename = "result")]
102    pub secret: String,
103}
104
105#[cfg(test)]
106mod test {
107    use super::*;
108    use serde_test::{assert_tokens, Token};
109
110    #[test]
111    fn test_recents() {
112        let p = Post {
113            href: "https://example.com".to_string(),
114            description: "Description".to_string(),
115            extended: "".to_string(),
116            meta: "meta".to_string(),
117            hash: "hash".to_string(),
118            time: DateTime::from_timestamp(61, 0).unwrap(),
119            shared: "no".to_string(),
120            toread: "no".to_string(),
121            tags: "tag".to_string(),
122        };
123        let pr = PostsRecent {
124            date: DateTime::from_timestamp(61, 0).unwrap(),
125            user: "User".to_string(),
126            posts: vec![p],
127        };
128
129        assert_tokens(
130            &pr,
131            &[
132                Token::Struct {
133                    name: "PostsRecent",
134                    len: 3,
135                },
136                Token::Str("user"),
137                Token::Str("User"),
138                Token::Str("date"),
139                Token::Str("1970-01-01T00:01:01Z"),
140                Token::Str("posts"),
141                Token::Seq { len: Some(1) },
142                Token::Struct {
143                    name: "Post",
144                    len: 9,
145                },
146                Token::Str("href"),
147                Token::Str("https://example.com"),
148                Token::Str("description"),
149                Token::Str("Description"),
150                Token::Str("extended"),
151                Token::Str(""),
152                Token::Str("meta"),
153                Token::Str("meta"),
154                Token::Str("hash"),
155                Token::Str("hash"),
156                Token::Str("time"),
157                Token::Str("1970-01-01T00:01:01Z"),
158                Token::Str("shared"),
159                Token::Str("no"),
160                Token::Str("toread"),
161                Token::Str("no"),
162                Token::Str("tags"),
163                Token::Str("tag"),
164                Token::StructEnd,
165                Token::SeqEnd,
166                Token::StructEnd,
167            ],
168        );
169
170        let body = r#"{"date":"2024-10-27T17:38:11Z","user":"person","posts":[{"href":"https://some.web.site","description":"Words","extended":"More Words","meta":"Some meta thing","hash":"AAABBBCCCDDDEEEFFF000","time":"2024-01-01T00:00:00Z","shared":"no","toread":"no","tags":"one two"}]}"#;
171
172        let val = serde_json::from_slice(body.as_bytes()).unwrap();
173        let pst = serde_json::from_value::<PostsRecent>(val).unwrap();
174        assert_eq!(pst.user, "person");
175        assert_eq!(pst.posts.len(), 1);
176        assert_eq!(pst.posts[0].href, "https://some.web.site");
177    }
178}