reactive_graph_runtime_graphql_schema/mutation/
command.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4use async_graphql::Context;
5use async_graphql::Error;
6use async_graphql::Object;
7use async_graphql::Result;
8use async_graphql::Value;
9
10use reactive_graph_command_api::CommandManager;
11use reactive_graph_command_model::component::CommandProperties::COMMAND_RESULT;
12use reactive_graph_graph::PropertyTypeDefinition;
13
14use crate::properties::GraphQLCommandResult;
15
16#[derive(Default)]
17pub struct MutationCommands;
18
19/// Mutations for plugins.
20#[Object]
21impl MutationCommands {
22    async fn execute(&self, context: &Context<'_>, name: String, args: Option<HashMap<String, Value>>) -> Result<Option<GraphQLCommandResult>> {
23        let command_manager = context.data::<Arc<dyn CommandManager + Send + Sync>>()?;
24        let command = command_manager.get_command(&name).map_err(|_| Error::new("No such command"))?;
25        let convert_result = convert_result();
26        let result = match args.map(convert_args) {
27            Some(args) => command.execute_with_args(args),
28            None => command.execute(),
29        }
30        .map_err(|_| Error::new("Command execution failed"))?
31        .map(convert_result);
32        Ok(result)
33    }
34}
35
36fn convert_args(args: HashMap<String, Value>) -> HashMap<String, serde_json::Value> {
37    args.into_iter().filter_map(map_entry).collect()
38}
39
40fn map_entry(entry: (String, Value)) -> Option<(String, serde_json::Value)> {
41    match entry.1.into_json() {
42        Ok(v) => Some((entry.0, v)),
43        Err(_) => None,
44    }
45}
46
47fn convert_result() -> impl FnOnce(serde_json::Value) -> GraphQLCommandResult {
48    |result: serde_json::Value| GraphQLCommandResult::new(COMMAND_RESULT.property_name(), result)
49}