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
use reqwest::RequestBuilder;
use serde::de::DeserializeOwned;

use crate::{
    error::{Error, TwitterError},
    rate_limit::RateLimit,
};

pub mod delete_2_lists_id;
pub mod delete_2_lists_id_members_user_id;
pub mod delete_2_tweets_id;
pub mod delete_2_users_id_bookmarks_tweet_id;
pub mod delete_2_users_id_followed_lists_list_id;
pub mod delete_2_users_id_likes_tweet_id;
pub mod delete_2_users_id_pinned_lists;
pub mod delete_2_users_id_retweets_source_tweet_id;
pub mod delete_2_users_source_user_id_blocking_target_user_id;
pub mod delete_2_users_source_user_id_following_target_user_id;
pub mod delete_2_users_source_user_id_muting_target_user_id;
pub mod get_2_compliance_jobs;
pub mod get_2_compliance_jobs_id;
pub mod get_2_dm_conversations_dm_conversation_id_dm_events;
pub mod get_2_dm_conversations_with_participant_id_dm_events;
pub mod get_2_dm_events;
pub mod get_2_lists_id;
pub mod get_2_lists_id_followers;
pub mod get_2_lists_id_members;
pub mod get_2_lists_id_tweets;
pub mod get_2_spaces;
pub mod get_2_spaces_by_creator_ids;
pub mod get_2_spaces_id;
pub mod get_2_spaces_id_buyers;
pub mod get_2_spaces_id_tweets;
pub mod get_2_spaces_search;
pub mod get_2_tweets;
pub mod get_2_tweets_compliance_stream;
pub mod get_2_tweets_count_all;
pub mod get_2_tweets_count_recent;
pub mod get_2_tweets_id;
pub mod get_2_tweets_id_liking_users;
pub mod get_2_tweets_id_quote_tweets;
pub mod get_2_tweets_id_retweeted_by;
pub mod get_2_tweets_sample10_stream;
pub mod get_2_tweets_sample_stream;
pub mod get_2_tweets_search_all;
pub mod get_2_tweets_search_recent;
pub mod get_2_tweets_search_stream;
pub mod get_2_tweets_search_stream_rules;
pub mod get_2_users;
pub mod get_2_users_by;
pub mod get_2_users_by_username_username;
pub mod get_2_users_compliance_stream;
pub mod get_2_users_id;
pub mod get_2_users_id_blocking;
pub mod get_2_users_id_bookmarks;
pub mod get_2_users_id_followed_lists;
pub mod get_2_users_id_followers;
pub mod get_2_users_id_following;
pub mod get_2_users_id_liked_tweets;
pub mod get_2_users_id_list_memberships;
pub mod get_2_users_id_mentions;
pub mod get_2_users_id_muting;
pub mod get_2_users_id_owned_lists;
pub mod get_2_users_id_pinned_lists;
pub mod get_2_users_id_timelines_reverse_chronological;
pub mod get_2_users_id_tweets;
pub mod get_2_users_me;
pub mod post_2_compliance_jobs;
pub mod post_2_dm_conversations;
pub mod post_2_dm_conversations_dm_conversation_id_message;
pub mod post_2_dm_conversations_with_participant_id_message;
pub mod post_2_lists;
pub mod post_2_lists_id_members;
pub mod post_2_oauth2_token_refresh_token;
pub mod post_2_tweets;
pub mod post_2_tweets_search_stream_rules;
pub mod post_2_users_id_blocking;
pub mod post_2_users_id_bookmarks;
pub mod post_2_users_id_followed_lists;
pub mod post_2_users_id_following;
pub mod post_2_users_id_likes;
pub mod post_2_users_id_muting;
pub mod post_2_users_id_pinned_lists;
pub mod post_2_users_id_retweets;
pub mod put_2_lists_id;
pub mod put_2_tweets_id_hidden;

pub trait Authentication {
    fn execute(
        &self,
        builder: RequestBuilder,
        method: &str,
        uri: &str,
        options: &[(&str, &str)],
    ) -> RequestBuilder;
}

pub struct BearerAuthentication {
    bearer_code: String,
}

impl BearerAuthentication {
    pub fn new<T: Into<String>>(bearer_code: T) -> Self {
        Self {
            bearer_code: bearer_code.into(),
        }
    }
}

impl Authentication for BearerAuthentication {
    fn execute(
        &self,
        builder: RequestBuilder,
        _method: &str,
        _uri: &str,
        _options: &[(&str, &str)],
    ) -> RequestBuilder {
        builder.bearer_auth(&self.bearer_code)
    }
}

pub async fn execute_twitter<T>(builder: RequestBuilder) -> Result<(T, Option<RateLimit>), Error>
where
    T: DeserializeOwned,
{
    let response = builder.send().await?;
    let status_code = response.status();
    let header = response.headers();
    let rate_limit = RateLimit::new(header);

    if status_code.is_success() {
        Ok((response.json::<T>().await?, rate_limit))
    } else {
        match response.json::<serde_json::Value>().await {
            Ok(value) => Err(Error::Twitter(
                TwitterError::new(&value, status_code),
                value,
                rate_limit,
            )),
            Err(err) => Err(Error::Other(format!("{:?}", err), Some(status_code))),
        }
    }
}