nostr_bbs_setup_skill/
lib.rs1#![warn(missing_docs)]
28
29use async_trait::async_trait;
30use thiserror::Error;
31
32use nostr_bbs_config::ForumConfig;
33
34#[derive(Debug, Error)]
36pub enum SetupError {
37 #[error("provider: {0}")]
39 Provider(String),
40 #[error("config: {0}")]
42 Config(String),
43 #[error("io: {0}")]
45 Io(String),
46 #[error("unsupported")]
48 Unsupported,
49 #[error("{provider}::{method} not yet implemented — scheduled for Sprint v12+")]
51 NotYetImplemented {
52 provider: &'static str,
54 method: &'static str,
56 },
57}
58
59#[derive(Debug, Clone)]
61pub struct ProvisionedResource {
62 pub kind: String,
64 pub id: String,
66 pub name: String,
68}
69
70#[async_trait(?Send)]
72pub trait Provider {
73 fn tier(&self) -> &'static str;
75
76 async fn provision(&self, cfg: &ForumConfig) -> Result<Vec<ProvisionedResource>, SetupError>;
78
79 async fn render_wrangler(
82 &self,
83 cfg: &ForumConfig,
84 resources: &[ProvisionedResource],
85 ) -> Result<String, SetupError>;
86}
87
88pub struct SelfHostProvider;
90
91#[async_trait(?Send)]
92impl Provider for SelfHostProvider {
93 fn tier(&self) -> &'static str {
94 "tier-1"
95 }
96
97 async fn provision(&self, _cfg: &ForumConfig) -> Result<Vec<ProvisionedResource>, SetupError> {
98 Ok(Vec::new())
101 }
102
103 async fn render_wrangler(
104 &self,
105 _cfg: &ForumConfig,
106 _resources: &[ProvisionedResource],
107 ) -> Result<String, SetupError> {
108 Err(SetupError::NotYetImplemented {
111 provider: "SelfHostProvider",
112 method: "render_wrangler",
113 })
114 }
115}
116
117pub struct CloudflareWorkersProvider;
119
120#[async_trait(?Send)]
121impl Provider for CloudflareWorkersProvider {
122 fn tier(&self) -> &'static str {
123 "tier-2"
124 }
125
126 async fn provision(&self, _cfg: &ForumConfig) -> Result<Vec<ProvisionedResource>, SetupError> {
127 Err(SetupError::NotYetImplemented {
130 provider: "CloudflareWorkersProvider",
131 method: "provision",
132 })
133 }
134
135 async fn render_wrangler(
136 &self,
137 _cfg: &ForumConfig,
138 _resources: &[ProvisionedResource],
139 ) -> Result<String, SetupError> {
140 Err(SetupError::NotYetImplemented {
141 provider: "CloudflareWorkersProvider",
142 method: "render_wrangler",
143 })
144 }
145}
146
147pub struct FlyDotIoProvider;
149
150#[async_trait(?Send)]
151impl Provider for FlyDotIoProvider {
152 fn tier(&self) -> &'static str {
153 "tier-3"
154 }
155
156 async fn provision(&self, _cfg: &ForumConfig) -> Result<Vec<ProvisionedResource>, SetupError> {
157 Err(SetupError::NotYetImplemented {
158 provider: "FlyDotIoProvider",
159 method: "provision",
160 })
161 }
162
163 async fn render_wrangler(
164 &self,
165 _cfg: &ForumConfig,
166 _resources: &[ProvisionedResource],
167 ) -> Result<String, SetupError> {
168 Err(SetupError::NotYetImplemented {
169 provider: "FlyDotIoProvider",
170 method: "render_wrangler",
171 })
172 }
173}
174
175pub struct TurnkeyProvider;
177
178#[async_trait(?Send)]
179impl Provider for TurnkeyProvider {
180 fn tier(&self) -> &'static str {
181 "tier-4"
182 }
183
184 async fn provision(&self, _cfg: &ForumConfig) -> Result<Vec<ProvisionedResource>, SetupError> {
185 Err(SetupError::NotYetImplemented {
186 provider: "TurnkeyProvider",
187 method: "provision",
188 })
189 }
190
191 async fn render_wrangler(
192 &self,
193 _cfg: &ForumConfig,
194 _resources: &[ProvisionedResource],
195 ) -> Result<String, SetupError> {
196 Err(SetupError::Unsupported)
199 }
200}
201
202pub struct KubernetesProvider;
204
205#[async_trait(?Send)]
206impl Provider for KubernetesProvider {
207 fn tier(&self) -> &'static str {
208 "tier-x"
209 }
210
211 async fn provision(&self, _cfg: &ForumConfig) -> Result<Vec<ProvisionedResource>, SetupError> {
212 Err(SetupError::NotYetImplemented {
213 provider: "KubernetesProvider",
214 method: "provision",
215 })
216 }
217
218 async fn render_wrangler(
219 &self,
220 _cfg: &ForumConfig,
221 _resources: &[ProvisionedResource],
222 ) -> Result<String, SetupError> {
223 Err(SetupError::NotYetImplemented {
224 provider: "KubernetesProvider",
225 method: "render_wrangler",
226 })
227 }
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233
234 #[test]
235 fn provider_tiers_match_taxonomy() {
236 assert_eq!(SelfHostProvider.tier(), "tier-1");
237 assert_eq!(CloudflareWorkersProvider.tier(), "tier-2");
238 assert_eq!(FlyDotIoProvider.tier(), "tier-3");
239 assert_eq!(TurnkeyProvider.tier(), "tier-4");
240 assert_eq!(KubernetesProvider.tier(), "tier-x");
241 }
242}