Skip to main content
Glama
component.rs4.88 kB
use object_tree::{ Hash, HashedNode, }; use petgraph::prelude::*; use super::{ PkgResult, SiPkgAttributeValue, SiPkgError, SiPkgPosition, Source, }; use crate::{ AttributeValueSpec, ComponentSpec, ComponentSpecVariant, PositionSpec, node::{ ComponentChildNode, PkgNode, }, }; #[derive(Clone, Debug)] pub struct SiPkgComponent<'a> { name: String, variant: ComponentSpecVariant, needs_destroy: bool, deletion_user_pk: Option<String>, unique_id: String, deleted: bool, hash: Hash, source: Source<'a>, } macro_rules! impl_component_children_from_graph { ($fn_name:ident, ComponentChildNode::$child_node:ident, $pkg_type:ident) => { pub fn $fn_name(&self) -> PkgResult<Vec<$pkg_type>> { let mut entries = vec![]; if let Some(child_idxs) = self .source .graph .neighbors_directed(self.source.node_idx, Outgoing) .find(|node_idx| { matches!( &self.source.graph[*node_idx].inner(), PkgNode::ComponentChild(ComponentChildNode::$child_node) ) }) { let child_node_idxs: Vec<_> = self .source .graph .neighbors_directed(child_idxs, Outgoing) .collect(); for child_idx in child_node_idxs { entries.push($pkg_type::from_graph(self.source.graph, child_idx)?); } } Ok(entries) } }; } impl<'a> SiPkgComponent<'a> { pub fn from_graph( graph: &'a Graph<HashedNode<PkgNode>, ()>, node_idx: NodeIndex, ) -> PkgResult<Self> { let hashed_node = &graph[node_idx]; let node = match hashed_node.inner() { PkgNode::Component(node) => node.clone(), unexpected => { return Err(SiPkgError::UnexpectedPkgNodeType( PkgNode::COMPONENT_KIND_STR, unexpected.node_kind_str(), )); } }; Ok(Self { name: node.name, variant: node.variant, needs_destroy: node.needs_destroy, deletion_user_pk: node.deletion_user_pk, deleted: node.deleted, unique_id: node.unique_id, hash: hashed_node.hash(), source: Source::new(graph, node_idx), }) } impl_component_children_from_graph!( attributes, ComponentChildNode::Attributes, SiPkgAttributeValue ); impl_component_children_from_graph!( input_sockets, ComponentChildNode::InputSockets, SiPkgAttributeValue ); impl_component_children_from_graph!( output_sockets, ComponentChildNode::OutputSockets, SiPkgAttributeValue ); impl_component_children_from_graph!(position, ComponentChildNode::Position, SiPkgPosition); pub fn name(&self) -> &str { self.name.as_str() } pub fn variant(&self) -> &ComponentSpecVariant { &self.variant } pub fn needs_destroy(&self) -> bool { self.needs_destroy } pub fn deletion_user_pk(&self) -> Option<&str> { self.deletion_user_pk.as_deref() } pub fn unique_id(&self) -> &str { self.unique_id.as_str() } pub fn deleted(&self) -> bool { self.deleted } pub fn hash(&self) -> Hash { self.hash } pub fn source(&self) -> &Source<'a> { &self.source } } impl<'a> TryFrom<SiPkgComponent<'a>> for ComponentSpec { type Error = SiPkgError; fn try_from(value: SiPkgComponent<'a>) -> Result<Self, Self::Error> { let mut builder = ComponentSpec::builder(); let position = value .position()? .pop() .ok_or(SiPkgError::ComponentMissingPosition(value.name().into()))?; builder .name(value.name()) .position(PositionSpec::try_from(position)?) .variant(value.variant().to_owned()) .needs_destroy(value.needs_destroy()) .deletion_user_pk(value.deletion_user_pk().map(ToString::to_string)) .unique_id(value.unique_id()) .deleted(value.deleted()); for attribute in value.attributes()? { builder.attribute(AttributeValueSpec::try_from(attribute)?); } for input_socket in value.input_sockets()? { builder.input_socket(AttributeValueSpec::try_from(input_socket)?); } for output_socket in value.output_sockets()? { builder.output_socket(AttributeValueSpec::try_from(output_socket)?); } Ok(builder.build()?) } }

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