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

ambee/giterated

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

Basic Issue data structures

Emilia - ⁨1⁩ year ago

parent: tbd commit: ⁨509aa4e

⁨giterated-models/src/issue/mod.rs⁩ - ⁨3755⁩ bytes
Raw
1 pub mod events;
2 pub mod operations;
3 pub mod values;
4
5 use std::{fmt::Display, str::FromStr};
6
7 use events::IssueTimeline;
8 use serde::{Deserialize, Serialize};
9
10 use crate::{object::GiteratedObject, repository::Repository, user::User};
11
12 /// An issue, defined by the [`Repository`] it is related to along with
13 /// its id.
14 ///
15 /// # Textual Format
16 /// An issue's textual reference is defined as:
17 ///
18 /// `#{id: u64}:{repository: Repository}`
19 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
20 pub struct Issue {
21 pub id: u64,
22 /// The repository the issue is related to
23 pub repository: Repository,
24 }
25
26 impl GiteratedObject for Issue {
27 fn object_name() -> &'static str {
28 "issue"
29 }
30
31 fn home_uri(&self) -> String {
32 self.repository.home_uri()
33 }
34
35 fn from_object_str(object_str: &str) -> Result<Self, anyhow::Error> {
36 Ok(Issue::from_str(object_str)?)
37 }
38 }
39
40 impl Display for Issue {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.write_str(&format!("#{}:{}", self.id, self.repository))
43 }
44 }
45
46 #[derive(Debug, thiserror::Error)]
47 #[error("couldn't parse issue")]
48 pub struct IssueParseError;
49
50 impl FromStr for Issue {
51 type Err = IssueParseError;
52
53 fn from_str(s: &str) -> Result<Self, Self::Err> {
54 // Remove the pound from the start
55 let s = s
56 .starts_with('#')
57 .then(|| s.replace('#', ""))
58 .ok_or(IssueParseError)?;
59 // Split the id from the repository
60 let (id, repository) = s.split_once(':').ok_or(IssueParseError)?;
61
62 // Parse the id and the repository
63 let id: u64 = id.parse().map_err(|_| IssueParseError)?;
64 let repository = Repository::from_str(repository).map_err(|_| IssueParseError)?;
65
66 Ok(Self { id, repository })
67 }
68 }
69
70 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
71 pub struct IssueInfo {
72 #[serde(flatten)]
73 pub basic: IssueInfoBasic,
74 pub body: String,
75 pub timeline: IssueTimeline,
76 }
77
78 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
79 pub struct IssueInfoBasic {
80 pub id: u64,
81 pub status: IssueStatus,
82 pub title: String,
83 pub tags: Vec<IssueTag>,
84 pub last_activity: chrono::DateTime<chrono::Utc>,
85 pub created: chrono::DateTime<chrono::Utc>,
86 pub creator: User,
87 pub statistics: IssueStatistics,
88 pub assignees: Vec<User>,
89 }
90
91 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
92 pub struct IssueStatistics {
93 pub comments: u64,
94 }
95
96 /// Tag (sometimes referred to as label) to categorize issues.
97 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
98 pub struct IssueTag {
99 pub category: String,
100 pub sub_category: Option<String>,
101 pub description: Option<String>,
102 }
103
104 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
105 pub enum IssueStatus {
106 Open,
107 Closed,
108 }
109
110 impl Display for IssueStatus {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 match self {
113 IssueStatus::Open => f.write_str("Open"),
114 IssueStatus::Closed => f.write_str("Closed"),
115 }
116 }
117 }
118
119 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
120 pub struct IssueComment {
121 /// Event id
122 pub id: u64,
123 /// Creation date
124 pub created: chrono::DateTime<chrono::Utc>,
125 /// The user who created the comment
126 pub creator: User,
127 /// Body of the comment
128 pub body: String,
129 }
130
131 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
132 pub struct IssueCommentRevision {
133 /// Event id
134 pub id: u64,
135 /// Creation date
136 pub created: chrono::DateTime<chrono::Utc>,
137 /// Body of the comment
138 pub body: String,
139 }
140