Skip to main content
Glama
socket.rs8.83 kB
use std::collections::{ HashMap, hash_map, }; use itertools::Itertools; use serde::{ Deserialize, Serialize, }; use super::{ ComponentError, ComponentResult, }; use crate::{ AttributeValue, AttributeValueId, Component, ComponentId, DalContext, InputSocketId, OutputSocketId, }; /// Represents a given [`Component`]'s [`crate::InputSocket`], identified by its /// (non-unique) [`InputSocketId`] and unique [`AttributeValueId`] #[derive(Eq, Hash, PartialEq, Clone, Debug, Copy, Serialize, Deserialize)] pub struct ComponentInputSocket { pub component_id: ComponentId, pub input_socket_id: InputSocketId, pub attribute_value_id: AttributeValueId, } /// Represents a given [`Component`]'s [`crate::OutputSocket`], identified by its /// (non-unique) [`OutputSocketId`] and unique [`AttributeValueId`] #[derive(Eq, Hash, PartialEq, Clone, Debug, Copy, Serialize, Deserialize)] pub struct ComponentOutputSocket { pub component_id: ComponentId, pub output_socket_id: OutputSocketId, pub attribute_value_id: AttributeValueId, } impl ComponentOutputSocket { /// Given a [`ComponentId`] and [`OutputSocketId`] find the [`ComponentOutputSocket`] pub async fn get_by_ids( ctx: &DalContext, component_id: ComponentId, output_socket_id: OutputSocketId, ) -> ComponentResult<Option<ComponentOutputSocket>> { let output_socket = Self::list_for_component_id(ctx, component_id) .await? .into_iter() .find(|socket| socket.output_socket_id == output_socket_id); Ok(output_socket) } /// Given a [`ComponentId`] and [`OutputSocketId`] find the [`ComponentOutputSocket`] /// returns an error if one is not found pub async fn get_by_ids_or_error( ctx: &DalContext, component_id: ComponentId, output_socket_id: OutputSocketId, ) -> ComponentResult<ComponentOutputSocket> { match Self::get_by_ids(ctx, component_id, output_socket_id).await? { Some(component_output_socket) => Ok(component_output_socket), None => Err(ComponentError::OutputSocketNotFoundForComponentId( output_socket_id, component_id, )), } } /// List all [`ComponentOutputSocket`]s for a given [`ComponentId`] pub async fn list_for_component_id( ctx: &DalContext, component_id: ComponentId, ) -> ComponentResult<Vec<Self>> { let mut result = Vec::new(); let socket_values = Component::attribute_values_for_all_sockets(ctx, component_id).await?; for attribute_value_id in socket_values { if let Some(output_socket_id) = AttributeValue::is_for(ctx, attribute_value_id) .await? .output_socket_id() { result.push(ComponentOutputSocket { component_id, output_socket_id, attribute_value_id, }); } } Ok(result) } /// List all [`AttributeValueId`]s for the given [`ComponentId`]s [`crate::OutputSocket`]s pub async fn attribute_values_for_component_id( ctx: &DalContext, component_id: ComponentId, ) -> ComponentResult<Vec<AttributeValueId>> { let mut result = HashMap::new(); let socket_values = Component::attribute_values_for_all_sockets(ctx, component_id).await?; for socket_value_id in socket_values { if let Some(output_socket_id) = AttributeValue::is_for(ctx, socket_value_id) .await? .output_socket_id() { match result.entry(output_socket_id) { hash_map::Entry::Vacant(entry) => { entry.insert(ComponentOutputSocket { component_id, attribute_value_id: socket_value_id, output_socket_id, }); } hash_map::Entry::Occupied(_) => { return Err(ComponentError::OutputSocketTooManyAttributeValues( output_socket_id, )); } } } } Ok(result .into_values() .map(|component_output_socket| component_output_socket.attribute_value_id) .collect_vec()) } pub async fn value_for_output_socket_id_for_component_id_opt( ctx: &DalContext, component_id: ComponentId, output_socket_id: OutputSocketId, ) -> ComponentResult<Option<serde_json::Value>> { let attribute_value_id = Self::get_by_ids_or_error(ctx, component_id, output_socket_id) .await? .attribute_value_id; let view = AttributeValue::view(ctx, attribute_value_id).await?; Ok(view) } } impl ComponentInputSocket { /// List all [`ComponentInputSocket`]s for a given [`ComponentId`] pub async fn list_for_component_id( ctx: &DalContext, component_id: ComponentId, ) -> ComponentResult<Vec<ComponentInputSocket>> { let mut result = Vec::new(); let socket_values = Component::attribute_values_for_all_sockets(ctx, component_id).await?; for attribute_value_id in socket_values { if let Some(input_socket_id) = AttributeValue::is_for(ctx, attribute_value_id) .await? .input_socket_id() { result.push(ComponentInputSocket { component_id, input_socket_id, attribute_value_id, }); } } Ok(result) } /// Given a [`ComponentId`] and [`InputSocketId`] find the [`ComponentInputSocket`] pub async fn get_by_ids( ctx: &DalContext, component_id: ComponentId, input_socket_id: InputSocketId, ) -> ComponentResult<Option<ComponentInputSocket>> { let input_socket = Self::list_for_component_id(ctx, component_id) .await? .into_iter() .find(|socket| socket.input_socket_id == input_socket_id); Ok(input_socket) } /// Given a [`ComponentId`] and [`InputSocketId`] find the [`ComponentInputSocket`] /// return an error if one is not found pub async fn get_by_ids_or_error( ctx: &DalContext, component_id: ComponentId, input_socket_id: InputSocketId, ) -> ComponentResult<ComponentInputSocket> { match Self::get_by_ids(ctx, component_id, input_socket_id).await? { Some(component_input_socket) => Ok(component_input_socket), None => Err(ComponentError::InputSocketNotFoundForComponentId( input_socket_id, component_id, )), } } /// List all [`AttributeValueId`]s for the given [`ComponentId`]s [`crate::InputSocket`]s pub async fn attribute_values_for_component_id( ctx: &DalContext, component_id: ComponentId, ) -> ComponentResult<Vec<AttributeValueId>> { let mut result = HashMap::new(); let socket_values = Component::attribute_values_for_all_sockets(ctx, component_id).await?; for socket_value_id in socket_values { if let Some(input_socket_id) = AttributeValue::is_for(ctx, socket_value_id) .await? .input_socket_id() { match result.entry(input_socket_id) { hash_map::Entry::Vacant(entry) => { entry.insert(ComponentInputSocket { component_id, attribute_value_id: socket_value_id, input_socket_id, }); } hash_map::Entry::Occupied(_) => { return Err(ComponentError::InputSocketTooManyAttributeValues( input_socket_id, )); } } } } Ok(result .into_values() .map(|input_socket| input_socket.attribute_value_id) .collect_vec()) } pub async fn value_for_input_socket_id_for_component_id_opt( ctx: &DalContext, component_id: ComponentId, input_socket_id: InputSocketId, ) -> ComponentResult<Option<serde_json::Value>> { let attribute_value_id = Self::get_by_ids_or_error(ctx, component_id, input_socket_id) .await? .attribute_value_id; let view = AttributeValue::view(ctx, attribute_value_id).await?; Ok(view) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server