aboutsummaryrefslogtreecommitdiffstats
path: root/src/abook.rs
blob: c7ceeb188c728f4020d58482840220a23d35c464 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// zotapi - Rust wrapper for the Zot API as implemented by Hubzilla
// Copyright (C) 2018  Harald Eilertsen <haraldei@anduin.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use crate::{client::Client, error::Error, XChan, ZotAPI};
use serde::Deserialize;
use std::convert::TryFrom;
use zotapi_derive::ZotAPI;

#[derive(Debug, Default, Deserialize, ZotAPI)]
pub struct Abook {
    #[serde(rename = "abook_id")]
    pub id: u32,

    #[serde(rename = "abook_account")]
    pub account: u32,

    #[serde(rename = "abook_channel")]
    pub channel: u32,

    #[serde(rename = "abook_xchan")]
    pub xchan_id: String,

    #[serde(skip)]
    pub xchan: XChan,

    #[serde(rename = "abook_my_perms")]
    pub my_perms: u16,

    #[serde(rename = "abook_their_perms")]
    pub their_perms: u16,

    // Closeness is a number between 0 and 99, but is somehow
    // returned as a string.
    #[serde(rename = "abook_closeness")]
    pub closeness: String,

    #[serde(rename = "abook_created")]
    pub created: String,

    #[serde(rename = "abook_updated")]
    pub updated: String,

    #[serde(rename = "abook_connected")]
    pub connected: String,

    #[serde(rename = "abook_dob")]
    pub dob: String,

    #[serde(rename = "abook_flags")]
    pub flags: u16,         // No longer used

    #[serde(rename = "abook_profile")]
    pub profile: String,

    #[serde(rename = "abook_blocked")]
    pub blocked: u8,

    #[serde(rename = "abook_ignored")]
    pub ignored: u8,

    #[serde(rename = "abook_hidden")]
    pub hidden: u8,

    #[serde(rename = "abook_archived")]
    pub archived: u8,

    #[serde(rename = "abook_pending")]
    pub pending: u8,

    #[serde(rename = "abook_unconnected")]
    pub unconnected: u8,  // Currently unused

    #[serde(rename = "abook_self")]
    pub myself: u8,       // original name `self`

    #[serde(rename = "abook_feed")]
    pub feed: u8,

    #[serde(rename = "abook_not_here")]
    pub not_here: u8,

    #[serde(rename = "abook_incl")]
    pub incl: String,

    #[serde(rename = "abook_excl")]
    pub excl: String,

    #[serde(rename = "abook_instance")]
    pub instance: String,

    #[serde(rename = "abook_role")]
    pub role: String,
}


impl<'a> TryFrom<&'a str> for Abook {
    type Error = Error;

    fn try_from(s: &'a str) -> Result<Self, Self::Error> {
        Ok(serde_json::from_str(s)?)
    }
}

#[derive(Debug, Default)]
pub struct AbookRequest {
    abook_id: Option<u32>,
}

impl AbookRequest {
    /// Limit to ABConfigs for a given contact
    ///
    /// `abook` is the abook id of the given contact
    pub fn with_abook_id(mut self, abook: u32) -> AbookRequest {
        self.abook_id = Some(abook);
        self
    }

    pub async fn fetch_raw(&self, client: &Client) -> Result<String, Error> {
        let mut req = client.get("abook");

        if let Some(id) = self.abook_id {
            req = req.query(&[("abook_id", id.to_string())]);
        }

        Ok(req.send().await?
            .text().await?)
    }

    pub async fn fetch(&self, client: &Client) -> Result<Vec<Abook>, Error> {
        let json: serde_json::Value = serde_json::from_str(&self.fetch_raw(&client).await?)?;
        let arr = json.as_array().ok_or("Abook: Not an array")?;
        let res: Vec<Abook> = arr.iter()
            .map(|v| {
                let mut abook: Abook = serde_json::from_value(v.clone()).unwrap();
                abook.xchan = serde_json::from_value(v.clone()).unwrap();
                abook
            })
            .collect::<_>();

        Ok(res)
    }
}