Skip to content

Commit

Permalink
current: Add CurrentAuthHandler::list_gists_for_authenticated_user (#…
Browse files Browse the repository at this point in the history
…328)

* current: Add function `list_gists_for_authenticated_user`

Add a new function to `CurrentAuthHandler` that allows paginating
through the authenticated user's gists.

* gists: bugfix: `content`, `truncated` are optional

The aren't always sent as a part of the response, per the [schema][1].

[1]: https://docs.github.com/en/rest/gists/gists?apiVersion=latest#list-gists-for-the-authenticated-user

* examples: Add example 'list_gists_for_token_holder'

This example demonstrates using the gists API to paginate through the
gists of the authenticated user and printing them in a tabular form.
  • Loading branch information
envp authored Apr 8, 2023
1 parent 79186b5 commit 68bb3cc
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 3 deletions.
42 changes: 42 additions & 0 deletions examples/list_gists_for_token_holder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use octocrab::Octocrab;

#[tokio::main]
async fn main() -> octocrab::Result<()> {
let token = std::env::var("GITHUB_TOKEN").expect("GITHUB_TOKEN env variable is required");

let octocrab = Octocrab::builder().personal_token(token).build()?;
let current_user_name = octocrab.current().user().await?.login;
let mut current_gist_page = octocrab
.current()
.list_gists_for_authenticated_user()
.per_page(1)
.send()
.await?;

let mut gists = current_gist_page.take_items();
while let Ok(Some(mut new_page)) = octocrab.get_page(&current_gist_page.next).await {
gists.extend(new_page.take_items());
current_gist_page = new_page;
}

println!(
"User '{username}' has {count} gists:",
username = current_user_name,
count = gists.len()
);
println!("id | url | [files...] | description");
for gist in gists {
println!(
"{id} | {url} | [{files}] | {description}",
id = gist.id,
url = gist.html_url.to_string(),
files = gist.files.into_keys().collect::<Vec<_>>().join(", "),
description = gist
.description
.unwrap_or("<No description>".into())
.escape_default(),
);
}

Ok(())
}
104 changes: 103 additions & 1 deletion src/api/current.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Get data about the currently authenticated user.
use crate::{
models::{self, Repository},
models::{self, gists::Gist, Repository},
Octocrab, Page, Result,
};
use chrono::{DateTime, Utc};
Expand Down Expand Up @@ -79,6 +79,45 @@ impl<'octo> CurrentAuthHandler<'octo> {
pub fn list_repos_for_authenticated_user(&self) -> ListReposForAuthenticatedUserBuilder<'octo> {
ListReposForAuthenticatedUserBuilder::new(self.crab)
}

/// List gists for the current authenticated user.
///
/// # Examples
///
/// 1. The following snippet retrieves the most recent gist:
/// ```no_run
/// # async fn run() -> octocrab::Result<()> {
/// octocrab::instance()
/// .current()
/// .list_gists_for_authenticated_user()
/// .per_page(1)
/// .page(1)
/// .send()
/// .await?;
/// # Ok(())
/// # }
/// ```
///
/// 2. This retrieves the first 100 gists, which is maximum number that
/// can be fetched in a single page:
/// ```no_run
/// # async fn run() -> octocrab::Result<()> {
/// octocrab::instance()
/// .current()
/// .list_gists_for_authenticated_user()
/// .per_page(100)
/// .page(1)
/// .send()
/// .await?;
/// # Ok(())
/// # }
/// ```
///
/// [See the GitHub API documentation](https://docs.github.com/en/rest/gists/gists?apiVersion=latest#list-gists-for-the-authenticated-user)
pub fn list_gists_for_authenticated_user(&self) -> ListGistsForAuthenticatedUserBuilder<'octo> {
// self.crab.get("/gists", None::<&()>).await
ListGistsForAuthenticatedUserBuilder::new(self.crab)
}
}

/// A builder pattern struct for listing starred repositories.
Expand Down Expand Up @@ -289,3 +328,66 @@ impl<'octo> ListReposForAuthenticatedUserBuilder<'octo> {
self.crab.get("/user/repos", (&self).into()).await
}
}

/// A builder struct for initializing query parameters for use with the
/// `/gists` endpoint.
///
/// Created by: [`CurrentAuthHandler::list_gists_for_authenticated_user`].
///
/// [`CurrentAuthHandler::list_repos_starred_by_authenticated_user`]: ./struct.CurrentAuthHandler.html#method.list_gists_for_authenticated_user
#[derive(serde::Serialize)]
pub struct ListGistsForAuthenticatedUserBuilder<'octo> {
/// Client under use for building the request.
#[serde(skip)]
crab: &'octo Octocrab,

/// Only show gists that were updated after the given ISO 8601 UTC timestamp.
#[serde(skip_serializing_if = "Option::is_none")]
since: Option<DateTime<Utc>>,

/// The number of results per page (max 100).
#[serde(skip_serializing_if = "Option::is_none")]
per_page: Option<u8>,

/// Page number of the results to fetch, starting at 1.
#[serde(skip_serializing_if = "Option::is_none")]
page: Option<u32>,
}

impl<'octo> ListGistsForAuthenticatedUserBuilder<'octo> {
/// Create a new builder using the given client and default options as
/// described in GitHub's API docs.
///
/// [See the GitHub API documentation](https://docs.github.com/en/rest/gists/gists?apiVersion=latest#list-gists-for-the-authenticated-user)
pub fn new(crab: &'octo Octocrab) -> Self {
Self {
crab,
since: None,
per_page: None,
page: None,
}
}

/// Only show gists that were updated after the given ISO 8601 UTC timestamp.
pub fn since(mut self, last_updated: DateTime<Utc>) -> Self {
self.since = Some(last_updated);
self
}

/// The number of results per page (max 100).
pub fn per_page(mut self, count: u8) -> Self {
self.per_page = Some(count);
self
}

/// Page number of the results to fetch, starting at 1.
pub fn page(mut self, page_num: u32) -> Self {
self.page = Some(page_num);
self
}

/// Sends the actual request.
pub async fn send(self) -> crate::Result<Page<Gist>> {
self.crab.get("/gists", Some(&self)).await
}
}
4 changes: 2 additions & 2 deletions src/models/gists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ pub struct Gist {
#[non_exhaustive]
#[derive(Debug, Deserialize)]
pub struct GistFile {
pub content: String,
pub content: Option<String>,
pub filename: String,
pub language: Option<String>,
pub r#type: String,
pub raw_url: Url,
pub size: u64,
pub truncated: bool,
pub truncated: Option<bool>,
}

#[non_exhaustive]
Expand Down

0 comments on commit 68bb3cc

Please sign in to comment.