Skip to main content
Glama
socket.rs5.11 kB
use std::{ io::{ BufRead, Write, }, str::FromStr, }; use object_tree::{ GraphError, NameStr, NodeChild, NodeKind, NodeWithChildren, ReadBytes, WriteBytes, read_key_value_line, read_key_value_line_opt, write_key_value_line, }; use super::{ PkgNode, read_unique_id, write_unique_id, }; use crate::{ SocketSpec, SocketSpecArity, SocketSpecKind, }; const KEY_KIND_STR: &str = "kind"; const KEY_NAME_STR: &str = "name"; const KEY_CONNECTION_ANNOTATIONS_STR: &str = "type"; const KEY_ARITY_STR: &str = "arity"; const KEY_FUNC_UNIQUE_ID_STR: &str = "func_unique_id"; const KEY_UI_HIDDEN_STR: &str = "ui_hidden"; #[derive(Clone, Debug)] pub struct SocketData { pub name: String, pub connection_annotations: String, pub kind: SocketSpecKind, pub arity: SocketSpecArity, pub func_unique_id: Option<String>, pub ui_hidden: bool, } #[derive(Clone, Debug)] pub struct SocketNode { pub name: String, pub data: Option<SocketData>, pub unique_id: Option<String>, } impl NameStr for SocketNode { fn name(&self) -> &str { &self.name } } impl WriteBytes for SocketNode { fn write_bytes<W: Write>(&self, writer: &mut W) -> Result<(), GraphError> { write_key_value_line(writer, KEY_NAME_STR, &self.name)?; if let Some(data) = &self.data { // KEY_KIND_STR string should be the first data field to be serialized, // since we use it to detect if the payload has a data field in read_bytes below write_key_value_line(writer, KEY_KIND_STR, data.kind)?; write_key_value_line(writer, KEY_ARITY_STR, data.arity)?; write_key_value_line( writer, KEY_CONNECTION_ANNOTATIONS_STR, data.connection_annotations.clone(), )?; write_key_value_line( writer, KEY_FUNC_UNIQUE_ID_STR, data.func_unique_id.as_deref().unwrap_or(""), )?; write_key_value_line(writer, KEY_UI_HIDDEN_STR, data.ui_hidden)?; } write_unique_id(writer, self.unique_id.as_deref())?; Ok(()) } } impl ReadBytes for SocketNode { fn read_bytes<R: BufRead>(reader: &mut R) -> Result<Option<Self>, GraphError> where Self: std::marker::Sized, { let name = read_key_value_line(reader, KEY_NAME_STR)?; let data = match read_key_value_line_opt(reader, KEY_KIND_STR)? { None => None, Some(kind_str) => { let kind = SocketSpecKind::from_str(&kind_str).map_err(GraphError::parse)?; let arity_str = read_key_value_line(reader, KEY_ARITY_STR)?; let arity = SocketSpecArity::from_str(&arity_str).map_err(GraphError::parse)?; // We have to check if the type_string has been set for backwards compatibility let connection_annotations = match read_key_value_line_opt(reader, KEY_CONNECTION_ANNOTATIONS_STR)? { None => serde_json::to_string(&vec![name.to_owned()])?, Some(s) => s, }; let func_unique_id_str = read_key_value_line(reader, KEY_FUNC_UNIQUE_ID_STR)?; let func_unique_id = if func_unique_id_str.is_empty() { None } else { Some(func_unique_id_str) }; let ui_hidden = bool::from_str(&read_key_value_line(reader, KEY_UI_HIDDEN_STR)?) .map_err(GraphError::parse)?; Some(SocketData { name: name.to_owned(), connection_annotations, kind, arity, func_unique_id, ui_hidden, }) } }; let unique_id = read_unique_id(reader)?; Ok(Some(Self { name, data, unique_id, })) } } impl NodeChild for SocketSpec { type NodeType = PkgNode; fn as_node_with_children(&self) -> NodeWithChildren<Self::NodeType> { NodeWithChildren::new( NodeKind::Tree, Self::NodeType::Socket(SocketNode { name: self.name.to_owned(), data: self.data.as_ref().map(|data| SocketData { name: self.name.to_owned(), connection_annotations: data.connection_annotations.to_owned(), kind: data.kind, arity: data.arity, func_unique_id: data.func_unique_id.to_owned(), ui_hidden: data.ui_hidden, }), unique_id: self.unique_id.to_owned(), }), self.inputs .iter() .map(|input| { Box::new(input.clone()) as Box<dyn NodeChild<NodeType = Self::NodeType>> }) .collect(), ) } }

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