Skip to main content

ephemeris_forge_github/api/model/
collaborator.rs

1use ephemeris_forge::{Observed, UserName};
2use facet::Facet;
3
4use super::team::PermissionFlags;
5use crate::Permission;
6
7/// A user with a direct grant on the repository.
8#[derive(Clone, Debug, Eq, PartialEq)]
9pub struct Collaborator {
10    /// The user's login.
11    pub user: UserName,
12    /// The user's permission.
13    pub permission: Observed<Permission>,
14}
15
16/// A pending invitation to collaborate on the repository.
17#[derive(Clone, Debug, Eq, PartialEq)]
18pub struct Invitation {
19    /// The invitation's identifier.
20    pub id: u64,
21    /// The invited user's login.
22    pub user: UserName,
23    /// The permission the invitation grants once accepted.
24    pub permission: Observed<Permission>,
25}
26
27/// The kind of account that owns a repository.
28#[derive(Clone, Copy, Debug, Eq, Facet, PartialEq)]
29#[repr(u8)]
30pub enum OwnerKind {
31    /// An organization, which can define custom repository roles.
32    #[facet(rename = "Organization")]
33    Organization,
34    /// A personal account.
35    #[facet(rename = "User")]
36    User,
37}
38
39/// The wire shape of GitHub's collaborator listing.
40#[derive(Facet)]
41pub(crate) struct CollaboratorResponse {
42    login: String,
43    #[facet(default)]
44    role_name: String,
45    #[facet(default)]
46    permissions: Option<PermissionFlags>,
47}
48
49#[derive(Facet)]
50pub(crate) struct Invitee {
51    login: String,
52}
53
54/// The wire shape of GitHub's invitation listing.
55#[derive(Facet)]
56pub(crate) struct InvitationResponse {
57    id: u64,
58    #[facet(default)]
59    invitee: Option<Invitee>,
60    #[facet(default)]
61    permissions: String,
62}
63
64/// The wire shape of GitHub's account lookup.
65#[derive(Facet)]
66pub(crate) struct OwnerResponse {
67    #[facet(rename = "type")]
68    pub(crate) kind: OwnerKind,
69}
70
71impl CollaboratorResponse {
72    pub(crate) fn into_collaborator(self) -> Option<Collaborator> {
73        Some(Collaborator {
74            user: UserName::try_from(self.login).ok()?,
75            permission: Permission::from_role_name(&self.role_name).map_or_else(
76                || {
77                    Permission::observe(
78                        "",
79                        self.permissions.as_ref().and_then(PermissionFlags::highest),
80                    )
81                },
82                Observed::Known,
83            ),
84        })
85    }
86}
87
88impl InvitationResponse {
89    pub(crate) fn into_invitation(self) -> Option<Invitation> {
90        Some(Invitation {
91            id: self.id,
92            user: UserName::try_from(self.invitee?.login).ok()?,
93            permission: Permission::observe(&self.permissions, None),
94        })
95    }
96}