Skip to main content

hmd_profile_general/
lib.rs

1use hmd_core::{BlockDescriptor, MetadataField, MetadataFieldKind, ProfileDescriptor};
2use schemars::{schema_for, JsonSchema};
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
6pub struct CalloutMeta {
7    pub id: Option<String>,
8    #[serde(rename = "type")]
9    pub type_: Option<String>,
10    pub title: Option<String>,
11}
12
13#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
14pub struct AsideMeta {
15    pub id: Option<String>,
16    pub title: Option<String>,
17}
18
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
20pub struct DetailsMeta {
21    pub id: Option<String>,
22    pub summary: Option<String>,
23    pub open: Option<bool>,
24}
25
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
27pub struct FigureMeta {
28    pub id: Option<String>,
29    pub src: String,
30    pub alt: String,
31    pub caption: Option<String>,
32}
33
34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
35pub struct CardsMeta {
36    pub id: Option<String>,
37    pub title: Option<String>,
38    pub columns: Option<u64>,
39}
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
42pub struct CardMeta {
43    pub id: Option<String>,
44    pub title: String,
45    pub href: Option<String>,
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
49pub struct TabsMeta {
50    pub id: Option<String>,
51    pub title: Option<String>,
52}
53
54#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
55pub struct TabMeta {
56    pub id: Option<String>,
57    pub label: String,
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
61pub struct MetricMeta {
62    pub id: Option<String>,
63    pub label: String,
64    pub value: serde_json::Value,
65    pub unit: Option<String>,
66    pub trend: Option<String>,
67}
68
69#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
70pub struct TimelineMeta {
71    pub id: Option<String>,
72    pub title: Option<String>,
73}
74
75#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
76pub struct EventMeta {
77    pub id: Option<String>,
78    pub at: Option<String>,
79    pub title: Option<String>,
80    pub kind: Option<String>,
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
84#[serde(rename_all = "camelCase")]
85pub struct GeneralProfileSchema {
86    pub callout: Option<CalloutMeta>,
87    pub aside: Option<AsideMeta>,
88    pub details: Option<DetailsMeta>,
89    pub figure: Option<FigureMeta>,
90    pub cards: Option<CardsMeta>,
91    pub card: Option<CardMeta>,
92    pub tabs: Option<TabsMeta>,
93    pub tab: Option<TabMeta>,
94    pub metric: Option<MetricMeta>,
95    pub timeline: Option<TimelineMeta>,
96    pub event: Option<EventMeta>,
97}
98
99const CALLOUT_FIELDS: &[MetadataField] = &[
100    MetadataField::optional("id", MetadataFieldKind::String),
101    MetadataField::optional("type", MetadataFieldKind::String),
102    MetadataField::optional("title", MetadataFieldKind::String),
103];
104const ASIDE_FIELDS: &[MetadataField] = &[
105    MetadataField::optional("id", MetadataFieldKind::String),
106    MetadataField::optional("title", MetadataFieldKind::String),
107];
108const DETAILS_FIELDS: &[MetadataField] = &[
109    MetadataField::optional("id", MetadataFieldKind::String),
110    MetadataField::optional("summary", MetadataFieldKind::String),
111    MetadataField::optional("open", MetadataFieldKind::Boolean),
112];
113const FIGURE_FIELDS: &[MetadataField] = &[
114    MetadataField::optional("id", MetadataFieldKind::String),
115    MetadataField::required("src", MetadataFieldKind::String),
116    MetadataField::required("alt", MetadataFieldKind::String),
117    MetadataField::optional("caption", MetadataFieldKind::String),
118];
119const CARDS_FIELDS: &[MetadataField] = &[
120    MetadataField::optional("id", MetadataFieldKind::String),
121    MetadataField::optional("title", MetadataFieldKind::String),
122    MetadataField::optional("columns", MetadataFieldKind::Number),
123];
124const CARD_FIELDS: &[MetadataField] = &[
125    MetadataField::optional("id", MetadataFieldKind::String),
126    MetadataField::required("title", MetadataFieldKind::String),
127    MetadataField::optional("href", MetadataFieldKind::String),
128];
129const TABS_FIELDS: &[MetadataField] = &[
130    MetadataField::optional("id", MetadataFieldKind::String),
131    MetadataField::optional("title", MetadataFieldKind::String),
132];
133const TAB_FIELDS: &[MetadataField] = &[
134    MetadataField::optional("id", MetadataFieldKind::String),
135    MetadataField::required("label", MetadataFieldKind::String),
136];
137const METRIC_FIELDS: &[MetadataField] = &[
138    MetadataField::optional("id", MetadataFieldKind::String),
139    MetadataField::required("label", MetadataFieldKind::String),
140    MetadataField::required("value", MetadataFieldKind::Any),
141    MetadataField::optional("unit", MetadataFieldKind::String),
142    MetadataField::optional("trend", MetadataFieldKind::String),
143];
144const TIMELINE_FIELDS: &[MetadataField] = &[
145    MetadataField::optional("id", MetadataFieldKind::String),
146    MetadataField::optional("title", MetadataFieldKind::String),
147];
148const EVENT_FIELDS: &[MetadataField] = &[
149    MetadataField::optional("id", MetadataFieldKind::String),
150    MetadataField::optional("at", MetadataFieldKind::String),
151    MetadataField::optional("title", MetadataFieldKind::String),
152    MetadataField::optional("kind", MetadataFieldKind::String),
153];
154
155const CARD_CHILDREN: &[&str] = &["card"];
156const TAB_CHILDREN: &[&str] = &["tab"];
157const EVENT_CHILDREN: &[&str] = &["event"];
158
159const BLOCKS: &[BlockDescriptor] = &[
160    BlockDescriptor {
161        block_type: "callout",
162        schema_id: "https://hmd.dev/schemas/general@0.1/callout.schema.json",
163        fields: CALLOUT_FIELDS,
164        allowed_child_block_types: None,
165    },
166    BlockDescriptor {
167        block_type: "aside",
168        schema_id: "https://hmd.dev/schemas/general@0.1/aside.schema.json",
169        fields: ASIDE_FIELDS,
170        allowed_child_block_types: None,
171    },
172    BlockDescriptor {
173        block_type: "details",
174        schema_id: "https://hmd.dev/schemas/general@0.1/details.schema.json",
175        fields: DETAILS_FIELDS,
176        allowed_child_block_types: None,
177    },
178    BlockDescriptor {
179        block_type: "figure",
180        schema_id: "https://hmd.dev/schemas/general@0.1/figure.schema.json",
181        fields: FIGURE_FIELDS,
182        allowed_child_block_types: None,
183    },
184    BlockDescriptor {
185        block_type: "cards",
186        schema_id: "https://hmd.dev/schemas/general@0.1/cards.schema.json",
187        fields: CARDS_FIELDS,
188        allowed_child_block_types: Some(CARD_CHILDREN),
189    },
190    BlockDescriptor {
191        block_type: "card",
192        schema_id: "https://hmd.dev/schemas/general@0.1/card.schema.json",
193        fields: CARD_FIELDS,
194        allowed_child_block_types: None,
195    },
196    BlockDescriptor {
197        block_type: "tabs",
198        schema_id: "https://hmd.dev/schemas/general@0.1/tabs.schema.json",
199        fields: TABS_FIELDS,
200        allowed_child_block_types: Some(TAB_CHILDREN),
201    },
202    BlockDescriptor {
203        block_type: "tab",
204        schema_id: "https://hmd.dev/schemas/general@0.1/tab.schema.json",
205        fields: TAB_FIELDS,
206        allowed_child_block_types: None,
207    },
208    BlockDescriptor {
209        block_type: "metric",
210        schema_id: "https://hmd.dev/schemas/general@0.1/metric.schema.json",
211        fields: METRIC_FIELDS,
212        allowed_child_block_types: None,
213    },
214    BlockDescriptor {
215        block_type: "timeline",
216        schema_id: "https://hmd.dev/schemas/general@0.1/timeline.schema.json",
217        fields: TIMELINE_FIELDS,
218        allowed_child_block_types: Some(EVENT_CHILDREN),
219    },
220    BlockDescriptor {
221        block_type: "event",
222        schema_id: "https://hmd.dev/schemas/general@0.1/event.schema.json",
223        fields: EVENT_FIELDS,
224        allowed_child_block_types: None,
225    },
226];
227
228pub const PROFILE: ProfileDescriptor = ProfileDescriptor {
229    id: "general@0.1",
230    name: "general",
231    version: "0.1",
232    source: "official",
233    blocks: BLOCKS,
234    reference_rules: &[],
235};
236
237pub fn descriptor() -> ProfileDescriptor {
238    PROFILE
239}
240
241pub fn register_profile() -> ProfileDescriptor {
242    descriptor()
243}
244
245pub fn json_schema() -> serde_json::Value {
246    serde_json::to_value(schema_for!(GeneralProfileSchema)).expect("serializes schema")
247}