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

ambee/giterated

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

Spinning

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨1788060

⁨plugins/giterated-issues/src/lib.rs⁩ - ⁨4235⁩ bytes
Raw
1 use std::{fmt::Display, str::FromStr};
2
3 use anyhow::Error;
4 use giterated_models::{object::GiteratedObject, repository::Repository};
5 use giterated_plugin::{local::PluginStackBuilder, plugin, StateUUID};
6 use handlers::{
7 create_issue_request, edit_issue_request, issue_get_setting_contents, issue_get_setting_name,
8 issue_post_comment_request, issue_set_setting_contents, issue_set_setting_name,
9 issue_value_author, issue_value_comment_count, issue_value_creation_date, query_issues_request,
10 };
11 use serde::{Deserialize, Serialize};
12 use setting::NotificationsOverride;
13 use sqlx::{postgres::PgConnectOptions, PgPool};
14 use tokio::{fs::File, io::AsyncReadExt, runtime::Runtime};
15 use toml::Table;
16 use tracing::{debug, info};
17
18 pub mod db;
19 pub mod handlers;
20 pub mod operations;
21 pub mod setting;
22 pub mod value;
23
24 plugin!(
25 name: "plugin name"
26 );
27
28 /// An issue, defined by the repository which owns it and its index.
29 ///
30 /// # Textual Format
31 /// An issue's textual format is defined as:
32 ///
33 /// `@{index: u32}:{repository: Repository}`
34 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
35 pub struct Issue {
36 pub repository: Repository,
37 pub id: u32,
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 impl GiteratedObject for Issue {
47 fn object_name() -> &'static str {
48 "issue"
49 }
50
51 fn home_uri(&self) -> String {
52 self.repository.home_uri()
53 }
54
55 fn from_object_str(object_str: &str) -> Result<Self, Error> {
56 Ok(Issue::from_str(object_str)?)
57 }
58 }
59
60 impl FromStr for Issue {
61 type Err = IssueParseError;
62
63 fn from_str(s: &str) -> Result<Self, Self::Err> {
64 let (index, repository) = s.split_once(':').ok_or(IssueParseError)?;
65
66 let id: u32 = index.parse().map_err(|_| IssueParseError)?;
67 let repository = Repository::from_str(repository).map_err(|_| IssueParseError)?;
68
69 Ok(Self { repository, id })
70 }
71 }
72
73 #[derive(Debug, thiserror::Error)]
74 #[error("error parsing issue")]
75 pub struct IssueParseError;
76
77 #[derive(Clone, Debug)]
78 pub struct IssuesPluginState {
79 pub pool: PgPool,
80 }
81
82 impl StateUUID for IssuesPluginState {
83 fn uuid() -> u128 {
84 todo!()
85 }
86 }
87
88 #[plugin::init]
89 pub fn init(builder: &mut PluginStackBuilder) -> Result<(), Error> {
90 let runtime = Runtime::new().unwrap();
91 let db_pool = runtime.block_on(async {
92 let config: Table = {
93 let mut file = File::open("Giterated.toml").await.unwrap();
94 let mut text = String::new();
95 file.read_to_string(&mut text).await.unwrap();
96 text.parse().unwrap()
97 };
98 let db_conn_options = PgConnectOptions::new()
99 .host(config["postgres"]["host"].as_str().unwrap())
100 .port(config["postgres"]["port"].as_integer().unwrap() as u16)
101 .database(config["postgres"]["database"].as_str().unwrap())
102 .username(config["postgres"]["user"].as_str().unwrap())
103 .password(config["postgres"]["password"].as_str().unwrap());
104 let db_pool = PgPool::connect_with(db_conn_options).await.unwrap();
105
106 debug!("Running database migrations...");
107 // sqlx::migrate!().run(&db_pool).await.unwrap();
108 info!("Connected");
109
110 db_pool
111 });
112
113 // ASYNC_RUNTIME.set(runtime).unwrap();
114
115 let plugin_state = IssuesPluginState { pool: db_pool };
116
117 // let mut builder: PluginStackBuilder<'_, IssuesPluginState> =
118 // PluginStackBuilder::new(plugin_state, state, init_vtable);
119
120 builder.object::<Issue>();
121
122 builder
123 .object_setting(issue_get_setting_name, issue_set_setting_name)
124 .object_setting(issue_get_setting_contents, issue_set_setting_contents);
125
126 builder.object_user_setting::<Issue, NotificationsOverride>();
127
128 builder
129 .value(issue_value_creation_date)
130 .value(issue_value_comment_count)
131 .value(issue_get_setting_name)
132 .value(issue_value_author);
133
134 builder
135 .operation(create_issue_request)
136 .operation(query_issues_request)
137 .operation(edit_issue_request)
138 .operation(issue_post_comment_request);
139
140 Ok(())
141 }
142