lgui_core/command/
handle.rs1use std::marker::PhantomData;
2
3use crate::application::ApplicationContext;
4
5use super::{Command, CommandContext};
6
7pub struct CommandHandle<C> {
8 application: ApplicationContext,
9 _command: PhantomData<fn() -> C>,
10}
11
12impl<C> Clone for CommandHandle<C> {
13 fn clone(&self) -> Self {
14 Self {
15 application: self.application.clone(),
16 _command: PhantomData,
17 }
18 }
19}
20
21impl<C> CommandHandle<C>
22where
23 C: Command,
24{
25 pub(crate) fn new(application: ApplicationContext) -> Self {
26 Self {
27 application,
28 _command: PhantomData,
29 }
30 }
31
32 pub async fn invoke(&self, args: C::Args) -> Result<C::Output, C::Error> {
33 let handler = self.application.command_registry().handler::<C>();
34 let result = self
35 .application
36 .scope(handler.invoke(
37 CommandContext::new(self.application.clone()),
38 Box::new(args),
39 ))
40 .await;
41 match result {
42 Ok(output) => Ok(output
43 .downcast::<C::Output>()
44 .map(|output| *output)
45 .unwrap_or_else(|_| {
46 panic!("command `{}` returned an invalid output type", C::NAME)
47 })),
48 Err(error) => Err(*error.downcast::<C::Error>().unwrap_or_else(|_| {
49 panic!("command `{}` returned an invalid error type", C::NAME)
50 })),
51 }
52 }
53}