1use std::collections::BTreeMap;
2use std::convert::Infallible;
3
4use tonic::codegen::async_trait;
5
6use crate::catalog::Catalog;
7use crate::error::{Error, Result};
8
9#[derive(Clone, Debug, Default, Eq, PartialEq)]
10pub struct Subject {
11 pub id: String,
12 pub kind: String,
13 pub display_name: String,
14 pub auth_source: String,
15}
16
17#[derive(Clone, Debug, Default, Eq, PartialEq)]
18pub struct Credential {
19 pub mode: String,
20 pub subject_id: String,
21 pub connection: String,
22 pub instance: String,
23}
24
25#[derive(Clone, Debug, Default, Eq, PartialEq)]
26pub struct Access {
27 pub policy: String,
28 pub role: String,
29}
30
31#[derive(Clone, Debug, Default, Eq, PartialEq)]
32pub struct Request {
33 pub token: String,
34 pub connection_params: BTreeMap<String, String>,
35 pub subject: Subject,
36 pub credential: Credential,
37 pub access: Access,
38}
39
40impl Request {
41 pub fn connection_param(&self, name: &str) -> Option<&str> {
42 self.connection_params.get(name).map(String::as_str)
43 }
44}
45
46#[derive(Clone, Debug, Eq, PartialEq)]
47pub struct Response<T> {
48 pub status: Option<u16>,
49 pub body: T,
50}
51
52impl<T> Response<T> {
53 pub fn new(status: u16, body: T) -> Self {
54 Self {
55 status: Some(status),
56 body,
57 }
58 }
59}
60
61pub fn ok<T>(body: T) -> Response<T> {
62 Response::new(200, body)
63}
64
65pub trait IntoResponse<T> {
66 fn into_response(self) -> Response<T>;
67}
68
69impl<T> IntoResponse<T> for Response<T> {
70 fn into_response(self) -> Response<T> {
71 self
72 }
73}
74
75impl<T> IntoResponse<T> for T {
76 fn into_response(self) -> Response<T> {
77 ok(self)
78 }
79}
80
81#[derive(Clone, Debug, Default, Eq, PartialEq)]
82pub struct RuntimeMetadata {
83 pub name: String,
84 pub display_name: String,
85 pub description: String,
86 pub version: String,
87}
88
89#[async_trait]
90pub trait Provider: Send + Sync + 'static {
91 async fn configure(
92 &self,
93 _name: &str,
94 _config: serde_json::Map<String, serde_json::Value>,
95 ) -> Result<()> {
96 Ok(())
97 }
98
99 fn metadata(&self) -> Option<RuntimeMetadata> {
100 None
101 }
102
103 fn warnings(&self) -> Vec<String> {
104 Vec::new()
105 }
106
107 async fn health_check(&self) -> Result<()> {
108 Ok(())
109 }
110
111 fn supports_session_catalog(&self) -> bool {
112 false
113 }
114
115 async fn catalog_for_request(&self, _request: &Request) -> Result<Option<Catalog>> {
116 Ok(None)
117 }
118
119 async fn close(&self) -> Result<()> {
120 Ok(())
121 }
122}
123
124impl From<Infallible> for Error {
125 fn from(_value: Infallible) -> Self {
126 Error::internal("unreachable infallible error")
127 }
128}