···4455use bytes::{Bytes, BytesMut};
66use luminary_macros::hashmap_schema;
77-use salvo::oapi::ToSchema;
77+use salvo::oapi::{BasicType, Components, Object, RefOr, Schema, ToSchema};
88use serde::{Serialize, ser::SerializeStruct};
99use tokio::sync::{RwLock, broadcast};
1010+1111+use crate::schema_ref_or;
10121113/// A collection of Luminary projects, keyed by project name.
1214#[hashmap_schema]
···2123/// Represents a Luminary project, consisting of a docker compose project.
2224///
2325/// This is derived entirely from that state of its services.
2424-#[derive(Debug, Clone, PartialEq, ToSchema)]
2626+#[derive(Debug, Clone, PartialEq)]
2527pub struct LuminaryProject {
2628 /// The name of this project
2729 pub name: String,
···5557 state.serialize_field("busy", &self.busy())?;
5658 state.serialize_field("services", &self.services)?;
5759 state.end()
6060+ }
6161+}
6262+6363+impl ToSchema for LuminaryProject {
6464+ fn to_schema(components: &mut Components) -> RefOr<Schema> {
6565+ return schema_ref_or!(
6666+ components,
6767+ Schema::Object(Box::new(
6868+ Object::new()
6969+ .property("name", Object::with_type(BasicType::String))
7070+ .required("name")
7171+ .property("status", LuminaryStatus::to_schema(components))
7272+ .required("status")
7373+ .property("busy", Object::with_type(BasicType::Boolean))
7474+ .required("busy")
7575+ .property("services", LuminaryServiceList::to_schema(components))
7676+ .required("services"),
7777+ ))
7878+ );
5879 }
5980}
6081
+17
packages/node/src/util.rs
···2020 .expect("User can not be obtained from a unprotected endpoint.")
2121 };
2222}
2323+2424+/// Helper macro to create or reference an OpenAPI schema.
2525+#[macro_export]
2626+macro_rules! schema_ref_or {
2727+ ($components:expr, $block:expr) => {{
2828+ let name = salvo::oapi::naming::assign_name::<Self>(Default::default());
2929+ let ref_or = salvo::oapi::RefOr::Ref(salvo::oapi::Ref::new(format!("#/components/schemas/{}", name)));
3030+3131+ if !$components.schemas.contains_key(&name) {
3232+ $components.schemas.insert(name.clone(), ref_or.clone());
3333+ let schema = $block;
3434+ $components.schemas.insert(name, schema)
3535+ }
3636+3737+ ref_or
3838+ }};
3939+}