JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Add repository settings

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨f8eaf38

⁨giterated-models/src/model/repository.rs⁩ - ⁨6055⁩ bytes
Raw
1 use std::fmt::{Display, Formatter};
2 use std::str::FromStr;
3
4 use serde::{Deserialize, Serialize};
5
6 use super::{instance::Instance, user::User};
7
8 /// A repository, defined by the instance it exists on along with
9 /// its owner and name.
10 ///
11 /// # Textual Format
12 /// A repository's textual reference is defined as:
13 ///
14 /// `{owner: User}/{name: String}@{instance: Instance}`
15 ///
16 /// # Examples
17 /// For the repository named `foo` owned by `barson:giterated.dev` on the instance
18 /// `giterated.dev`, the following [`Repository`] initialization would
19 /// be valid:
20 ///
21 /// ```
22 /// let repository = Repository {
23 /// owner: User::from_str("barson:giterated.dev").unwrap(),
24 /// name: String::from("foo"),
25 /// instance: Instance::from_str("giterated.dev").unwrap()
26 /// };
27 ///
28 /// // This is correct
29 /// assert_eq!(Repository::from_str("barson:giterated.dev/[email protected]").unwrap(), repository);
30 /// ```
31 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
32 pub struct Repository {
33 pub owner: User,
34 pub name: String,
35 /// Instance the repository is on
36 pub instance: Instance,
37 }
38
39 impl ToString for Repository {
40 fn to_string(&self) -> String {
41 format!("{}/{}@{}", self.owner, self.name, self.instance.to_string())
42 }
43 }
44
45 impl TryFrom<String> for Repository {
46 type Error = ();
47
48 fn try_from(value: String) -> Result<Self, Self::Error> {
49 Self::from_str(&value)
50 }
51 }
52
53 impl FromStr for Repository {
54 type Err = ();
55
56 fn from_str(s: &str) -> Result<Self, Self::Err> {
57 let mut by_ampersand = s.split('@');
58 let mut path_split = by_ampersand.next().unwrap().split('/');
59
60 let instance = Instance::from_str(by_ampersand.next().unwrap()).unwrap();
61 let owner = User::from_str(path_split.next().unwrap()).unwrap();
62 let name = path_split.next().unwrap().to_string();
63
64 Ok(Self {
65 instance,
66 owner,
67 name,
68 })
69 }
70 }
71
72 /// Visibility of the repository to the general eye
73 #[derive(PartialEq, Eq, Debug, Hash, Serialize, Deserialize, Clone, sqlx::Type)]
74 #[sqlx(type_name = "visibility", rename_all = "lowercase")]
75 pub enum RepositoryVisibility {
76 Public,
77 Unlisted,
78 Private,
79 }
80
81 /// Implements [`Display`] for [`RepositoryVisiblity`] using [`Debug`]
82 impl Display for RepositoryVisibility {
83 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
84 write!(f, "{:?}", self)
85 }
86 }
87
88 #[derive(Clone, Debug, Serialize, Deserialize)]
89 pub struct RepositoryView {
90 /// Name of the repository
91 ///
92 /// This is different than the [`Repository`] name,
93 /// which may be a path.
94 pub name: String,
95 /// Owner of the Repository
96 pub owner: User,
97 /// Repository description
98 pub description: Option<String>,
99 /// Repository visibility
100 pub visibility: RepositoryVisibility,
101 /// Default branch of the repository
102 pub default_branch: String,
103 /// Last commit made to the repository
104 pub latest_commit: Option<Commit>,
105 /// Revision of the displayed tree
106 pub tree_rev: Option<String>,
107 /// Repository tree
108 pub tree: Vec<RepositoryTreeEntry>,
109 }
110
111 #[derive(Debug, Clone, Serialize, Deserialize)]
112 pub enum RepositoryObjectType {
113 Tree,
114 Blob,
115 }
116
117 /// Stored info for our tree entries
118 #[derive(Debug, Clone, Serialize, Deserialize)]
119 pub struct RepositoryTreeEntry {
120 /// Name of the tree/blob
121 pub name: String,
122 /// Type of the tree entry
123 pub object_type: RepositoryObjectType,
124 /// Git supplies us with the mode at all times, and people like it displayed.
125 pub mode: i32,
126 /// File size
127 pub size: Option<usize>,
128 /// Last commit made to the tree/blob
129 pub last_commit: Option<Commit>,
130 }
131
132 impl RepositoryTreeEntry {
133 // I love you Emilia <3
134 pub fn new(name: &str, object_type: RepositoryObjectType, mode: i32) -> Self {
135 Self {
136 name: name.to_string(),
137 object_type,
138 mode,
139 size: None,
140 last_commit: None,
141 }
142 }
143 }
144
145 #[derive(Debug, Clone, Serialize, Deserialize)]
146 pub struct RepositoryTreeEntryWithCommit {
147 pub tree_entry: RepositoryTreeEntry,
148 pub commit: Commit,
149 }
150
151 /// Info about a git commit
152 #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
153 pub struct Commit {
154 /// Unique commit ID
155 pub oid: String,
156 /// Full commit message
157 pub message: Option<String>,
158 /// Who created the commit
159 pub author: CommitSignature,
160 /// Who committed the commit
161 pub committer: CommitSignature,
162 /// Time when the commit happened
163 pub time: chrono::NaiveDateTime,
164 }
165
166 /// Gets all info from [`git2::Commit`] for easy use
167 impl From<git2::Commit<'_>> for Commit {
168 fn from(commit: git2::Commit<'_>) -> Self {
169 Self {
170 oid: commit.id().to_string(),
171 message: commit.message().map(|message| message.to_string()),
172 author: commit.author().into(),
173 committer: commit.committer().into(),
174 time: chrono::NaiveDateTime::from_timestamp_opt(commit.time().seconds(), 0).unwrap(),
175 }
176 }
177 }
178
179 /// Git commit signature
180 #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
181 pub struct CommitSignature {
182 pub name: Option<String>,
183 pub email: Option<String>,
184 pub time: chrono::NaiveDateTime,
185 }
186
187 /// Converts the signature from git2 into something usable without explicit lifetimes.
188 impl From<git2::Signature<'_>> for CommitSignature {
189 fn from(signature: git2::Signature<'_>) -> Self {
190 Self {
191 name: signature.name().map(|name| name.to_string()),
192 email: signature.email().map(|email| email.to_string()),
193 time: chrono::NaiveDateTime::from_timestamp_opt(signature.when().seconds(), 0).unwrap(),
194 }
195 }
196 }
197
198 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
199 pub struct RepositorySummary {
200 pub repository: Repository,
201 pub owner: User,
202 pub visibility: RepositoryVisibility,
203 pub description: Option<String>,
204 pub last_commit: Option<Commit>,
205 }
206