1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use actix_web::{web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize, Default)]
pub struct Catalog {
pub services: Vec<Service>,
}
#[derive(Serialize, Default)]
pub struct Service {
pub name: String,
pub id: String,
pub description: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub requires: Vec<Permission>,
pub bindable: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub instances_retrievable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bindings_retrievable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_context_updates: Option<bool>,
#[serde(skip_serializing_if = "HashMap::is_empty")]
pub metadata: HashMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub plan_updateable: Option<bool>,
pub plans: Vec<ServicePlan>,
}
#[derive(Serialize)]
#[serde(rename_all = "snake_case")]
#[allow(unused)]
pub enum Permission {
SyslogDrain,
RouteForwarding,
VolumeMount,
}
#[derive(Serialize, Default)]
pub struct ServicePlan {
pub id: String,
pub name: String,
pub description: String,
#[serde(skip_serializing_if = "HashMap::is_empty")]
pub metadata: HashMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub free: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bindable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub plan_updateable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub maximum_polling_duration: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub maintenance_info: Option<MaintenanceInfo>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct MaintenanceInfo {
version: String,
description: Option<String>,
}
pub async fn get_catalog(provider: web::Data<CatalogProvider>) -> impl Responder {
HttpResponse::Ok().json(provider.get_catalog())
}
pub fn build_catalog() -> Catalog {
let mut catalog = Catalog::default();
let mut free_plan = ServicePlan::default();
free_plan.id = "free".to_string();
free_plan.name = "free".to_string();
free_plan.description = "Free plan".to_string();
free_plan.maximum_polling_duration = Some(60);
let mut hello_wasi = Service::default();
hello_wasi.id = "hellowasi".to_string();
hello_wasi.name = "hellowasi".to_string();
hello_wasi.description = "Hello world in WASI".to_string();
hello_wasi.tags.push("wasi".to_string());
hello_wasi.requires.push(Permission::VolumeMount);
hello_wasi.bindable = true;
hello_wasi.plans.push(free_plan);
catalog.services.push(hello_wasi);
catalog
}
pub struct CatalogProvider {
pub catalog: Catalog,
}
impl CatalogProvider {
pub fn new(catalog: Catalog) -> Self {
CatalogProvider { catalog }
}
pub fn get_catalog(&self) -> &Catalog {
&self.catalog
}
}