stardust_xr_fusion/
lib.rs

1//! A library for Stardust XR clients to use with abstractions over the client, nodes, and event loop.
2
3#![allow(dead_code)]
4#![allow(clippy::derivable_impls)]
5
6use std::{error::Error, fmt::Debug, marker::PhantomData, os::fd::OwnedFd};
7
8pub use client::*;
9use serde::Serialize;
10pub use stardust_xr as core;
11pub use stardust_xr::values;
12use stardust_xr::{
13	messenger::MethodResponse, scenegraph::ScenegraphError, schemas::flex::serialize,
14};
15
16use crate::node::NodeError;
17
18#[macro_use]
19pub mod node;
20
21pub mod audio;
22pub mod client;
23pub mod drawable;
24pub mod fields;
25pub mod input;
26pub mod items;
27pub mod objects;
28mod protocol;
29pub mod root;
30pub mod scenegraph;
31pub mod spatial;
32pub mod query_impl;
33
34pub use stardust_xr::schemas::dbus::query as query;
35pub use stardust_xr::schemas::dbus::list_query as list_query;
36pub use stardust_xr::schemas::impl_queryable_for_proxy;
37
38pub struct TypedMethodResponse<T: Serialize>(pub(crate) MethodResponse, pub(crate) PhantomData<T>);
39impl<T: Serialize> TypedMethodResponse<T> {
40	pub fn send_ok(self, value: T) {
41		self.send(Ok::<T, NodeError>(value))
42	}
43	pub fn send<E: Error>(self, result: Result<T, E>) {
44		let data = match result {
45			Ok(d) => d,
46			Err(e) => {
47				self.0.send(Err(ScenegraphError::MemberError {
48					error: e.to_string(),
49				}));
50				return;
51			}
52		};
53		let Ok(serialized) = stardust_xr::schemas::flex::serialize(data) else {
54			self.0.send(Err(ScenegraphError::MemberError {
55				error: "Internal: Failed to serialize".to_string(),
56			}));
57			return;
58		};
59		self.0.send(Ok((&serialized, Vec::<OwnedFd>::new())));
60	}
61	pub fn wrap<E: Error, F: FnOnce() -> Result<T, E>>(self, f: F) {
62		self.send(f())
63	}
64	pub fn wrap_async<E: Error>(
65		self,
66		f: impl Future<Output = Result<(T, Vec<OwnedFd>), E>> + Send + 'static,
67	) {
68		tokio::task::spawn(async move {
69			let (value, fds) = match f.await {
70				Ok(d) => d,
71				Err(e) => {
72					self.0.send(Err(ScenegraphError::MemberError {
73						error: e.to_string(),
74					}));
75					return;
76				}
77			};
78			let Ok(serialized) = serialize(value) else {
79				self.0.send(Err(ScenegraphError::MemberError {
80					error: "Internal: Failed to serialize".to_string(),
81				}));
82				return;
83			};
84			self.0.send(Ok((&serialized, fds)));
85		});
86	}
87}
88impl<T: Serialize> Debug for TypedMethodResponse<T> {
89	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90		f.debug_struct("TypedMethodResponse").finish()
91	}
92}