1use async_trait::async_trait;
2use facet::Facet;
3use facet_json::{DeserializeError, JsonError};
4use issuecraft_ql::{ExecutionEngine, ExecutionResult, ProjectId, UserId};
5
6#[derive(thiserror::Error, Debug)]
7pub enum ClientError {
8 #[error("Not implemented")]
9 NotImplemented,
10 #[error("This action is not supported by the chosen backend")]
11 NotSupported,
12 #[error("IQL error: {0}")]
13 IqlError(#[from] issuecraft_ql::IqlError),
14 #[error("Deserialization error: {0}")]
15 DeserializationError(#[from] DeserializeError<JsonError>),
16 #[error("Client specific: {0}")]
17 ClientSpecific(String),
18}
19
20#[derive(Debug, Clone, Facet)]
21pub struct UserInfo {
22 pub name: String,
23 pub display: Option<String>,
24 pub email: String,
25}
26
27#[derive(Debug, Clone, Facet)]
28pub struct ProjectInfo {
29 pub description: Option<String>,
30 pub owner: UserId,
31 pub display: Option<String>,
32}
33
34#[derive(Debug, Clone, Facet)]
35#[repr(C)]
36pub enum CloseReason {
37 Duplicate,
38 WontFix,
39 Fixed,
40}
41
42#[derive(Debug, Clone, Facet)]
43#[repr(C)]
44pub enum IssueStatus {
45 Open,
46 Assigned,
47 Blocked,
48 Closed { reason: CloseReason },
49}
50
51#[derive(Debug, Clone, Facet)]
52#[repr(C)]
53pub enum Priority {
54 Low,
55 Medium,
56 High,
57 Critical,
58}
59
60#[derive(Debug, Clone, Facet)]
61pub struct IssueInfo {
62 pub title: String,
63 pub description: Option<String>,
64 pub status: IssueStatus,
65 pub project: ProjectId,
66 pub priority: Option<Priority>,
67 pub assignee: Option<UserId>,
68}
69
70#[derive(Debug, Clone, Facet)]
71pub struct CommentInfo {
72 pub created_at: time::UtcDateTime,
73 pub content: String,
74 pub author: UserId,
75}
76
77#[derive(Debug, Clone)]
78pub enum AuthenticationInfo {
79 Password { password: String },
80 Token { token: String },
81 Certificate { path: Vec<u8> },
82}
83
84#[derive(Debug, Clone)]
85pub struct LoginInfo {
86 pub user: String,
87 pub auth: AuthenticationInfo,
88}
89
90#[async_trait]
91pub trait Client {
92 async fn login(&mut self, _login: LoginInfo) -> Result<(), ClientError> {
93 Err(ClientError::NotSupported)
94 }
95 async fn logout(&mut self) -> Result<(), ClientError> {
96 Err(ClientError::NotSupported)
97 }
98 async fn query(&mut self, query: &str) -> Result<ExecutionResult, ClientError>;
99}
100
101#[async_trait]
102impl<E: ExecutionEngine + Send> Client for E {
103 async fn query(&mut self, query: &str) -> Result<ExecutionResult, ClientError> {
104 let result = self.execute(query).await?;
105 Ok(result)
106 }
107}
108
109pub trait Backend {
110 fn init(&mut self) {}
111}