Skip to content

Commit

Permalink
Merge pull request #2 from aoyagikouhei/feature-user-connection-status
Browse files Browse the repository at this point in the history
Feature user connection status
  • Loading branch information
aoyagikouhei committed Jan 22, 2024
2 parents 835a31b + d259aab commit a24f15a
Show file tree
Hide file tree
Showing 15 changed files with 117 additions and 28 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## Changes

### v0.10.0 (2024/01/22)
* add user filed connection_status and most_recent_tweet_id

### v0.9.0 (2023/12/16)
* add get /2/users/search
- add get /2/trend/by/woeid/:woeid
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "twapi-v2"
version = "0.9.0"
version = "0.10.0"
authors = ["aoyagikouhei <aoyagi.kouhei@gmail.com>"]
license = "MIT"
edition = "2021"
Expand Down
2 changes: 1 addition & 1 deletion examples/oauth-web/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/streaming/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion maker/fields/user.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
---

value: created_at, description, entities, id, location, name, pinned_tweet_id, profile_image_url, protected, public_metrics, url, username, verified, verified_type, withheld
value: connection_status, created_at, description, entities, id, location, most_recent_tweet_id, name, pinned_tweet_id, profile_image_url, protected, public_metrics, url, username, verified, verified_type, withheld
2 changes: 1 addition & 1 deletion maker/responses/jobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ response:
created_at:
type: date
type:
type: enum_string
type: enum_single
value: tweets, users
name:
type: string
Expand Down
6 changes: 6 additions & 0 deletions maker/responses/users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
response:
type: object
properties:
connection_status:
type: array
items:
type: string
created_at:
type: date
description:
Expand All @@ -15,6 +19,8 @@ response:
required: true
location:
type: string
most_recent_tweet_id:
type: string
name:
type: string
required: true
Expand Down
40 changes: 21 additions & 19 deletions src/api/get_2_trends_by_woeid_woeid.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use serde::{Serialize, Deserialize};
use crate::responses::{trends::Trends};
use crate::responses::trends::Trends;
use crate::{
api::{execute_twitter, Authentication},
error::Error,
rate_limit::RateLimit,
};
use reqwest::RequestBuilder;
use crate::{error::Error, rate_limit::RateLimit, api::{execute_twitter, Authentication}};
use serde::{Deserialize, Serialize};

const URL: &str = "https://api.twitter.com/2/trends/by/woeid/:woeid";





#[derive(Debug, Clone, Default)]
pub struct Api {
woeid: String,
Expand All @@ -20,38 +20,40 @@ impl Api {
woeid: woeid.to_owned(),
}
}

pub fn build(self, authentication: &impl Authentication) -> RequestBuilder {

let client = reqwest::Client::new();
let url = URL.replace(":woeid", &self.woeid);
let builder = client
.get(&url)
;
let builder = client.get(&url);
authentication.execute(builder, "GET", &url, &[])
}

pub async fn execute(self, authentication: &impl Authentication) -> Result<(Response, Option<RateLimit>), Error> {
pub async fn execute(
self,
authentication: &impl Authentication,
) -> Result<(Response, Option<RateLimit>), Error> {
execute_twitter(self.build(authentication)).await
}
}



#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Response {
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Trends>,
pub data: Option<Trends>,
#[serde(flatten)]
pub extra: std::collections::HashMap<String, serde_json::Value>,
}

impl Response {
pub fn is_empty_extra(&self) -> bool {
let res = self.extra.is_empty() &&
self.data.as_ref().map(|it| it.is_empty_extra()).unwrap_or(true);
let res = self.extra.is_empty()
&& self
.data
.as_ref()
.map(|it| it.is_empty_extra())
.unwrap_or(true);
if !res {
println!("Response {:?}", self.extra);
println!("Response {:?}", self.extra);
}
res
}
Expand Down
10 changes: 9 additions & 1 deletion src/fields/user_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::collections::HashSet;

#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Clone)]
pub enum UserFields {
#[serde(rename = "connection_status")]
ConnectionStatus,
#[serde(rename = "created_at")]
CreatedAt,
#[serde(rename = "description")]
Expand All @@ -13,6 +15,8 @@ pub enum UserFields {
Id,
#[serde(rename = "location")]
Location,
#[serde(rename = "most_recent_tweet_id")]
MostRecentTweetId,
#[serde(rename = "name")]
Name,
#[serde(rename = "pinned_tweet_id")]
Expand All @@ -38,11 +42,13 @@ pub enum UserFields {
impl UserFields {
pub fn all() -> HashSet<Self> {
let mut result = HashSet::new();
result.insert(Self::ConnectionStatus);
result.insert(Self::CreatedAt);
result.insert(Self::Description);
result.insert(Self::Entities);
result.insert(Self::Id);
result.insert(Self::Location);
result.insert(Self::MostRecentTweetId);
result.insert(Self::Name);
result.insert(Self::PinnedTweetId);
result.insert(Self::ProfileImageUrl);
Expand All @@ -60,11 +66,13 @@ impl UserFields {
impl std::fmt::Display for UserFields {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::ConnectionStatus => write!(f, "connection_status"),
Self::CreatedAt => write!(f, "created_at"),
Self::Description => write!(f, "description"),
Self::Entities => write!(f, "entities"),
Self::Id => write!(f, "id"),
Self::Location => write!(f, "location"),
Self::MostRecentTweetId => write!(f, "most_recent_tweet_id"),
Self::Name => write!(f, "name"),
Self::PinnedTweetId => write!(f, "pinned_tweet_id"),
Self::ProfileImageUrl => write!(f, "profile_image_url"),
Expand All @@ -81,6 +89,6 @@ impl std::fmt::Display for UserFields {

impl Default for UserFields {
fn default() -> Self {
Self::CreatedAt
Self::ConnectionStatus
}
}
25 changes: 24 additions & 1 deletion src/responses/jobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub struct Jobs {
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option<String>,
pub r#type: Option<Type>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -41,6 +41,29 @@ impl Jobs {
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Type {
#[serde(rename = "tweets")]
Tweets,
#[serde(rename = "users")]
Users,
}

impl std::fmt::Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Tweets => write!(f, "tweets"),
Self::Users => write!(f, "users"),
}
}
}

impl Default for Type {
fn default() -> Self {
Self::Tweets
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Status {
#[serde(rename = "created")]
Expand Down
4 changes: 4 additions & 0 deletions src/responses/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Users {
#[serde(skip_serializing_if = "Option::is_none")]
pub connection_status: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -13,6 +15,8 @@ pub struct Users {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub most_recent_tweet_id: Option<String>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub pinned_tweet_id: Option<String>,
Expand Down
2 changes: 1 addition & 1 deletion tests/get_2_users.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;
use twapi_v2::api::{execute_twitter, get_2_users, BearerAuthentication};

// BEARER_CODE=XXXXX cargo test test_get_2_users_users -- --nocapture --test-threads=1
// BEARER_CODE=XXXXX cargo test test_get_2_users_users --all-features -- --nocapture --test-threads=1

#[tokio::test]
async fn test_get_2_users_users() -> Result<()> {
Expand Down
22 changes: 22 additions & 0 deletions tests/get_2_users_by_oauth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use anyhow::Result;
use twapi_v2::api::{execute_twitter, get_2_users_by};
use twapi_v2::oauth10a::OAuthAuthentication;

// CONSUMER_KEY=XXXX CONSUMER_SECRET=XXXX ACCESS_KEY=XXXX ACCESS_SECRET=XXXX cargo test test_get_2_users_by_by_oauth --all-features -- --nocapture --test-threads=1

#[tokio::test]
async fn test_get_2_users_by_by_oauth() -> Result<()> {
let auth = OAuthAuthentication::new(
std::env::var("CONSUMER_KEY").unwrap_or_default(),
std::env::var("CONSUMER_SECRET").unwrap_or_default(),
std::env::var("ACCESS_KEY").unwrap_or_default(),
std::env::var("ACCESS_SECRET").unwrap_or_default(),
);
let builder =
get_2_users_by::Api::open("retrip_gourmet,uv_technology,barley_tea_0522").build(&auth);
let (res, _rate_limit) = execute_twitter::<serde_json::Value>(builder).await?;
println!("{}", serde_json::to_string(&res).unwrap());
let response = serde_json::from_value::<get_2_users_by::Response>(res)?;
assert_eq!(response.is_empty_extra(), true);
Ok(())
}
21 changes: 21 additions & 0 deletions tests/get_2_users_oauth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use anyhow::Result;
use twapi_v2::api::{execute_twitter, get_2_users};
use twapi_v2::oauth10a::OAuthAuthentication;

// CONSUMER_KEY=XXXX CONSUMER_SECRET=XXXX ACCESS_KEY=XXXX ACCESS_SECRET=XXXX cargo test test_get_2_users_users_oauth --all-features -- --nocapture --test-threads=1

#[tokio::test]
async fn test_get_2_users_users_oauth() -> Result<()> {
let auth = OAuthAuthentication::new(
std::env::var("CONSUMER_KEY").unwrap_or_default(),
std::env::var("CONSUMER_SECRET").unwrap_or_default(),
std::env::var("ACCESS_KEY").unwrap_or_default(),
std::env::var("ACCESS_SECRET").unwrap_or_default(),
);
let builder = get_2_users::Api::open("1660518823991336966,1524979284024078336").build(&auth);
let (res, _rate_limit) = execute_twitter::<serde_json::Value>(builder).await?;
println!("{}", serde_json::to_string(&res).unwrap());
let response = serde_json::from_value::<get_2_users::Response>(res)?;
assert_eq!(response.is_empty_extra(), true);
Ok(())
}

0 comments on commit a24f15a

Please sign in to comment.