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

ambee/giterated

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

So. Much. Work.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨b05f964

⁨giterated-plugins/giterated-issues/src/lib.rs⁩ - ⁨4323⁩ bytes
Raw
1 use std::{fmt::Display, str::FromStr, sync::OnceLock};
2
3 use anyhow::Error;
4 use giterated_models::{object::GiteratedObject, repository::Repository};
5 use giterated_plugin::{
6 handle::PluginInitializationState,
7 new_stack::{FFIPluginMeta, PluginState},
8 HostVTable, InitializationVTable,
9 };
10 use giterated_plugin_sys::PluginStackBuilder;
11 use handlers::{
12 create_issue_request, edit_issue_request, issue_get_setting_contents, issue_get_setting_name,
13 issue_post_comment_request, issue_set_setting_contents, issue_set_setting_name,
14 issue_value_author, issue_value_comment_count, issue_value_creation_date, query_issues_request,
15 };
16 use serde::{Deserialize, Serialize};
17 use setting::{Contents, NotificationsOverride};
18 use sqlx::PgPool;
19 use value::{Author, CommentCount, CreationDate, Name};
20
21 pub mod db;
22 pub mod handlers;
23 pub mod operations;
24 pub mod setting;
25 pub mod value;
26
27 /// An issue, defined by the repository which owns it and its index.
28 ///
29 /// # Textual Format
30 /// An issue's textual format is defined as:
31 ///
32 /// `@{index: u32}:{repository: Repository}`
33 #[derive(Hash, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
34 pub struct Issue {
35 pub repository: Repository,
36 pub id: u32,
37 }
38
39 impl Display for Issue {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.write_str(&format!("{}:{}", self.id, self.repository))
42 }
43 }
44
45 impl GiteratedObject for Issue {
46 fn object_name() -> &'static str {
47 "issue"
48 }
49
50 fn home_uri(&self) -> String {
51 self.repository.home_uri()
52 }
53
54 fn from_object_str(object_str: &str) -> Result<Self, Error> {
55 Ok(Issue::from_str(object_str)?)
56 }
57 }
58
59 impl FromStr for Issue {
60 type Err = IssueParseError;
61
62 fn from_str(s: &str) -> Result<Self, Self::Err> {
63 let (index, repository) = s.split_once(':').ok_or_else(|| IssueParseError)?;
64
65 let id: u32 = index.parse().map_err(|_| IssueParseError)?;
66 let repository = Repository::from_str(repository).map_err(|_| IssueParseError)?;
67
68 Ok(Self { repository, id })
69 }
70 }
71
72 #[derive(Debug, thiserror::Error)]
73 #[error("error parsing issue")]
74 pub struct IssueParseError;
75
76 static INIT_VTABLE: OnceLock<InitializationVTable> = OnceLock::new();
77
78 #[no_mangle]
79 pub extern "C" fn plugin_meta() -> FFIPluginMeta {
80 const PLUGIN_NAME: &str = "Giterated [Issues]";
81 const PLUGIN_VERSION: &str = "0.1.0";
82
83 FFIPluginMeta {
84 name: PLUGIN_NAME.as_ptr(),
85 name_len: PLUGIN_NAME.len(),
86 version: PLUGIN_VERSION.as_ptr(),
87 version_len: PLUGIN_VERSION.len(),
88 }
89 }
90
91 #[no_mangle]
92 pub extern "C" fn load_host_vtable(_vtable: &HostVTable) {
93 println!("Loading vtable");
94 }
95
96 #[no_mangle]
97 pub extern "C" fn load_initialization_vtable(init_vtable: &InitializationVTable) {
98 INIT_VTABLE.set(init_vtable.clone()).unwrap();
99 println!("Loaded initialization vtable");
100 }
101
102 #[no_mangle]
103 pub extern "C" fn initialize() -> PluginState {
104 // tracing_subscriber::fmt()
105 // .pretty()
106 // .with_thread_names(true)
107 // .with_max_level(Level::TRACE)
108 // .init();
109
110 PluginState {
111 inner: Box::into_raw(Box::new(())),
112 }
113 }
114
115 #[no_mangle]
116 pub extern "C" fn initialize_registration(
117 state: *mut PluginInitializationState,
118 ) -> *mut PluginInitializationState {
119 // let _guard: tracing::span::EnteredSpan = trace_span!("initialize_registration").entered();
120 let init_vtable = INIT_VTABLE.get().unwrap();
121
122 let plugin_state = { todo!() };
123
124 let mut builder = PluginStackBuilder::new(plugin_state, state, init_vtable);
125
126 builder.object::<Issue>();
127
128 builder
129 .object_setting(issue_get_setting_name, issue_set_setting_name)
130 .object_setting(issue_get_setting_contents, issue_set_setting_contents);
131
132 builder.object_user_setting::<Issue, NotificationsOverride>();
133
134 builder
135 .value(issue_value_creation_date)
136 .value(issue_value_comment_count)
137 .value(issue_get_setting_name)
138 .value(issue_value_author);
139
140 builder
141 .operation_handler(create_issue_request)
142 .operation_handler(query_issues_request)
143 .operation_handler(edit_issue_request)
144 .operation_handler(issue_post_comment_request);
145
146 state
147 }
148
149 #[derive(Clone, Debug)]
150 pub struct IssuesPluginState {
151 pub pool: PgPool,
152 }
153