Skip to content

Commit

Permalink
Add Octocrab::users() and UsersHandler::repos (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamjpotts authored Aug 31, 2023
1 parent 71ad4a7 commit b84edac
Show file tree
Hide file tree
Showing 8 changed files with 463 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Currently, the following modules are available as of version `0.17`.
- [`search`] GitHub's search API.
- [`teams`] Teams.
- [`gists`] GitHub's gists API
- [`users`] Users.

[`models`]: https://docs.rs/octocrab/latest/octocrab/models/index.html
[`auth`]: https://docs.rs/octocrab/latest/octocrab/auth/index.html
Expand All @@ -58,6 +59,7 @@ Currently, the following modules are available as of version `0.17`.
[`search`]: https://docs.rs/octocrab/latest/octocrab/search/struct.SearchHandler.html
[`teams`]: https://docs.rs/octocrab/latest/octocrab/teams/struct.TeamHandler.html
[`gists`]: https://docs.rs/octocrab/latest/octocrab/gists/struct.GistsHandler.html
[`users`]: https://docs.rs/octocrab/latest/octocrab/gists/struct.UsersHandler.html

#### Getting a Pull Request
```rust
Expand Down
1 change: 1 addition & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ pub mod ratelimit;
pub mod repos;
pub mod search;
pub mod teams;
pub mod users;
pub mod workflows;
21 changes: 21 additions & 0 deletions src/api/users.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! The users API.
mod user_repos;

pub use self::user_repos::ListUserReposBuilder;
use crate::Octocrab;

pub struct UserHandler<'octo> {
crab: &'octo Octocrab,
user: String,
}

impl<'octo> UserHandler<'octo> {
pub(crate) fn new(crab: &'octo Octocrab, user: String) -> Self {
Self { crab, user }
}

pub fn repos(&self) -> ListUserReposBuilder<'_, '_> {
ListUserReposBuilder::new(self)
}
}
99 changes: 99 additions & 0 deletions src/api/users/user_repos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use crate::api::users::UserHandler;
use crate::Page;

/// A builder pattern struct for listing a user's repositories.
///
/// created by [`UserHandler::repos`]
///
/// [`UserHandler::repos`]: ./struct.UserHandler.html#method.repos
#[derive(serde::Serialize)]
pub struct ListUserReposBuilder<'octo, 'b> {
#[serde(skip)]
handler: &'b UserHandler<'octo>,
#[serde(skip_serializing_if = "Option::is_none")]
r#type: Option<crate::params::users::repos::Type>,
#[serde(skip_serializing_if = "Option::is_none")]
sort: Option<crate::params::repos::Sort>,
#[serde(skip_serializing_if = "Option::is_none")]
direction: Option<crate::params::Direction>,
#[serde(skip_serializing_if = "Option::is_none")]
per_page: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
page: Option<u32>,
}

impl<'octo, 'b> ListUserReposBuilder<'octo, 'b> {
pub(crate) fn new(handler: &'b UserHandler<'octo>) -> Self {
Self {
handler,
r#type: None,
sort: None,
direction: None,
per_page: None,
page: None,
}
}

/// Repository ownership type.
pub fn r#type(mut self, r#type: impl Into<crate::params::users::repos::Type>) -> Self {
self.r#type = Some(r#type.into());
self
}

/// What to sort results by.
pub fn sort(mut self, sort: impl Into<crate::params::repos::Sort>) -> Self {
self.sort = Some(sort.into());
self
}

/// The direction of the sort.
pub fn direction(mut self, direction: impl Into<crate::params::Direction>) -> Self {
self.direction = Some(direction.into());
self
}

/// Results per page (max 100).
pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
self.per_page = Some(per_page.into());
self
}

/// Page number of the results to fetch.
pub fn page(mut self, page: impl Into<u32>) -> Self {
self.page = Some(page.into());
self
}

/// Sends the actual request.
pub async fn send(self) -> crate::Result<Page<crate::models::Repository>> {
let route = format!("/users/{user}/repos", user = self.handler.user);
self.handler.crab.get(route, Some(&self)).await
}
}

#[cfg(test)]
mod tests {
#[tokio::test]
async fn serialize() {
let octocrab = crate::Octocrab::default();
let handler = octocrab.users("foo");
let request = handler
.repos()
.r#type(crate::params::users::repos::Type::Member)
.sort(crate::params::repos::Sort::Updated)
.direction(crate::params::Direction::Ascending)
.per_page(87)
.page(3u8);

assert_eq!(
serde_json::to_value(request).unwrap(),
serde_json::json!({
"type": "member",
"sort": "updated",
"direction": "asc",
"per_page": 87,
"page": 3,
})
)
}
}
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
//! - [`repos::releases`] Repositories
//! - [`search`] Using GitHub's search.
//! - [`teams`] Teams
//! - [`users`] Users
//!
//! #### Getting a Pull Request
//! ```no_run
Expand Down Expand Up @@ -246,6 +247,7 @@ use crate::service::middleware::extra_headers::ExtraHeadersLayer;
#[cfg(feature = "retry")]
use crate::service::middleware::retry::RetryConfig;

use crate::api::users;
use auth::{AppAuth, Auth};
use models::{AppId, InstallationId, InstallationToken};

Expand Down Expand Up @@ -1065,6 +1067,11 @@ impl Octocrab {
teams::TeamHandler::new(self, owner.into())
}

/// Creates a [`users::UserHandler`] for the specified user
pub fn users(&self, user: impl Into<String>) -> users::UserHandler {
users::UserHandler::new(self, user.into())
}

/// Creates a [`workflows::WorkflowsHandler`] for the specified repository that allows
/// you to access GitHub's workflows API.
pub fn workflows(
Expand Down
18 changes: 18 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,21 @@ pub mod workflows {
All,
}
}

pub mod users {
//! Parameter types for the users API.
pub mod repos {
/// What ownership type to filter a user repository list by.
///
/// See https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-repositories-for-a-user
#[derive(Debug, Clone, Copy, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Type {
All,
Owner,
Member,
}
}
}
Loading

0 comments on commit b84edac

Please sign in to comment.