1use std::sync::Arc;
2use serde::Serialize;
3
4use crate::runtime::handle::ExtensionHandle;
5use crate::runtime::state::OverviewHandler;
6use crate::runtime::handlers::SingleEntryContext;
7use crate::error::Error;
8
9#[derive(Serialize)]
31#[serde(rename_all = "camelCase")]
32pub struct OverviewField {
33 id: String,
34 label: String,
35 #[serde(skip)]
36 handler: OverviewHandler,
37}
38
39impl OverviewField {
40 pub fn new<F, Fut>(id: impl Into<String>, label: impl Into<String>, handler: F) -> Self
42 where
43 F: Fn(SingleEntryContext, ExtensionHandle) -> Fut + Send + Sync + 'static,
44 Fut: Future<Output = Result<Option<String>, Error>> + Send + 'static,
45 {
46 Self {
47 id: id.into(),
48 label: label.into(),
49 handler: Arc::new(move |ctx, handle| {
50 let fut = handler(ctx, handle);
51 Box::pin(async move { fut.await.map_err(Error::into_jrpc) })
52 }),
53 }
54 }
55}
56
57#[derive(Serialize)]
59#[serde(rename_all = "camelCase")]
60pub struct OverviewSection {
61 label: String,
62 children: Vec<OverviewNode>,
63}
64
65impl OverviewSection {
66 pub fn new(label: impl Into<String>) -> Self {
68 Self {
69 label: label.into(),
70 children: Vec::new()
71 }
72 }
73
74 pub fn with_children(mut self, children: &mut Vec<OverviewNode>) -> Self {
76 self.children.append(children);
77 self
78 }
79
80 pub fn with_child(mut self, child: OverviewNode) -> Self {
82 self.children.push(child);
83 self
84 }
85}
86
87#[derive(Serialize)]
90#[serde(tag = "type", rename_all = "snake_case")]
91pub enum OverviewNode {
92 Section(OverviewSection),
93 Field(OverviewField),
94}
95
96impl From<OverviewField> for OverviewNode {
97 fn from(field: OverviewField) -> Self {
98 OverviewNode::Field(field)
99 }
100}
101
102impl From<OverviewSection> for OverviewNode {
103 fn from(section: OverviewSection) -> Self {
104 OverviewNode::Section(section)
105 }
106}
107
108impl OverviewNode {
109 pub(crate) fn extract_handlers(&self) -> Vec<(String, OverviewHandler)> {
110 match self {
111 Self::Field(field) => vec![(field.id.clone(), Arc::clone(&field.handler))],
112 Self::Section(section) => section
113 .children
114 .iter()
115 .flat_map(|child| child.extract_handlers())
116 .collect(),
117 }
118 }
119}