use std::fmt;
use serde::{Deserialize, Serialize};
use crate::users::User;
use crate::{Future, Github, Stream};
#[derive(Clone, Copy)]
pub enum Permission {
Pull,
Push,
Admin,
}
impl fmt::Display for Permission {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Permission::Pull => "pull",
Permission::Push => "push",
Permission::Admin => "admin",
}
.fmt(f)
}
}
pub struct RepoTeams {
github: Github,
owner: String,
repo: String,
}
impl RepoTeams {
#[doc(hidden)]
pub fn new<O, R>(github: Github, owner: O, repo: R) -> Self
where
O: Into<String>,
R: Into<String>,
{
RepoTeams {
github,
owner: owner.into(),
repo: repo.into(),
}
}
pub fn list(&self) -> Future<Vec<Team>> {
self.github
.get(&format!("/repos/{}/{}/teams", self.owner, self.repo))
}
pub fn iter(&self) -> Stream<Team> {
self.github
.get_stream(&format!("/repos/{}/{}/teams", self.owner, self.repo))
}
}
pub struct OrgTeams {
github: Github,
org: String,
}
impl OrgTeams {
#[doc(hidden)]
pub fn new<O>(github: Github, org: O) -> Self
where
O: Into<String>,
{
OrgTeams {
github,
org: org.into(),
}
}
pub fn list(&self) -> Future<Vec<Team>> {
self.github.get(&format!("/orgs/{}/teams", self.org))
}
pub fn get(&self, number: u64) -> OrgTeamActions {
OrgTeamActions::new(self.github.clone(), number)
}
pub fn create(&self, team_options: &TeamOptions) -> Future<Team> {
self.github
.post(&format!("/orgs/{}/teams", self.org), json!(team_options))
}
pub fn iter(&self) -> Stream<Team> {
self.github.get_stream(&format!("/orgs/{}/teams", self.org))
}
pub fn add_repo_permission<N>(
&self,
team_id: u64,
repo_name: N,
permission: Permission,
) -> Future<()>
where
N: Into<String>,
{
self.github.put_no_response(
&format!("/teams/{}/repos/{}/{}", team_id, self.org, repo_name.into()),
json_lit!({ "permission": permission.to_string() }),
)
}
}
pub struct OrgTeamActions {
github: Github,
number: u64,
}
impl OrgTeamActions {
#[doc(hidden)]
pub fn new(github: Github, number: u64) -> Self {
OrgTeamActions { github, number }
}
fn path(&self, suffix: &str) -> String {
format!("/teams/{}{}", self.number, suffix)
}
pub fn get(&self) -> Future<Team> {
self.github.get(&self.path(""))
}
pub fn update(&self, team_options: &TeamOptions) -> Future<Team> {
self.github.patch(&self.path(""), json!(team_options))
}
pub fn delete(&self) -> Future<()> {
self.github.delete(&self.path(""))
}
pub fn list_members(&self) -> Future<Vec<User>> {
self.github.get(&self.path("/members"))
}
pub fn iter_members(&self) -> Stream<User> {
self.github.get_stream(&self.path("/members"))
}
pub fn add_user(&self, user: &str, user_options: TeamMemberOptions) -> Future<TeamMember> {
self.github.put(
&self.path(&format!("/memberships/{}", user)),
json!(user_options),
)
}
pub fn remove_user(&self, user: &str) -> Future<()> {
self.github
.delete(&self.path(&format!("/memberships/{}", user)))
}
}
#[derive(Debug, Deserialize)]
pub struct TeamMember {
pub url: String,
pub role: TeamMemberRole,
pub state: TeamMemberState,
}
#[derive(Debug, Serialize)]
pub struct TeamMemberOptions {
pub role: TeamMemberRole,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum TeamMemberRole {
Member,
Maintainer,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TeamMemberState {
Active,
Pending,
}
#[derive(Debug, Deserialize)]
pub struct Team {
pub id: u64,
pub url: String,
pub name: String,
pub slug: String,
pub description: Option<String>,
pub privacy: String,
pub permission: String,
pub members_url: String,
pub repositories_url: String,
}
#[derive(Debug, Serialize)]
pub struct TeamOptions {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub privacy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub permission: Option<String>,
}