Skip to main content
Glama
leaves.rs4.36 kB
//! This module contains all "leaves" that can be created underneath [`RootProp`](crate::RootProp) //! subtrees for a [`SchemaVariant`](crate::SchemaVariant). In this domain, a "leaf" is considered //! to an entry of a immediate child [`map`](crate::PropKind::Map) underneath "/root". use telemetry::prelude::*; use super::{ SchemaVariantError, SchemaVariantResult, }; use crate::{ AttributePrototype, AttributePrototypeId, DalContext, Func, FuncBackendKind, FuncId, Prop, PropId, SchemaVariant, SchemaVariantId, attribute::prototype::argument::AttributePrototypeArgument, func::leaf::{ LeafInput, LeafKind, }, workspace_snapshot::edge_weight::EdgeWeightKind, }; impl SchemaVariant { /// Insert an [`object`](crate::PropKind::Object) entry into a "/root" subtree of /// [`map`](crate::PropKind::Map) with a [`Func`](crate::Func) that matches the provided /// [`LeafKind`] in order to populate the subtree entry. /// /// The [`PropId`](crate::Prop) for the child [`map`](crate::PropKind::Map) of "/root" /// corresponding to the [`LeafKind`] is returned. pub async fn add_leaf( ctx: &DalContext, func_id: FuncId, schema_variant_id: SchemaVariantId, leaf_kind: LeafKind, inputs: Vec<LeafInput>, ) -> SchemaVariantResult<(PropId, AttributePrototypeId)> { let func = Func::get_by_id(ctx, func_id).await?; // Ensure the func matches what we need. if func.backend_kind != FuncBackendKind::JsAttribute { return Err(SchemaVariantError::LeafFunctionMustBeJsAttribute(func.id)); } if func.backend_response_type != leaf_kind.into() { return Err(SchemaVariantError::LeafFunctionMismatch( func_id, func.backend_response_type, leaf_kind, )); } // The key is the name of the func. This assume func names are unique. let key = Some(func.name.to_owned()); // Gather the item and map props. let item_prop_id = SchemaVariant::find_leaf_item_prop(ctx, schema_variant_id, leaf_kind).await?; let map_prop_id = Prop::parent_prop_id_by_id(ctx, item_prop_id) .await? .ok_or_else(|| SchemaVariantError::LeafMapPropNotFound(item_prop_id))?; // Clear existing prototypes as needed. if let Some(prototype_id) = AttributePrototype::find_for_prop(ctx, item_prop_id, &None) .await .map_err(Box::new)? { debug!(%prototype_id, %item_prop_id, "removing attribute prototype without key for leaf item prop"); AttributePrototype::remove(ctx, prototype_id) .await .map_err(Box::new)?; } if let Some(prototype_id) = AttributePrototype::find_for_prop(ctx, item_prop_id, &key) .await .map_err(Box::new)? { debug!(%prototype_id, %item_prop_id, ?key, "removing attribute prototype for leaf item prop and key that already exists"); AttributePrototype::remove(ctx, prototype_id) .await .map_err(Box::new)?; } // Create the new prototype and add an edge to the item prop using a populated key. let attribute_prototype_id = AttributePrototype::new(ctx, func_id) .await .map_err(Box::new)? .id(); Prop::add_edge_to_attribute_prototype( ctx, item_prop_id, attribute_prototype_id, EdgeWeightKind::Prototype(key), ) .await?; // Now that we have the prototype, we can process all inputs and create an attribute prototype argument that // sources its value from the input prop. for input in inputs { let input_prop_id = SchemaVariant::find_root_child_prop_id( ctx, schema_variant_id, input.location.into(), ) .await?; AttributePrototypeArgument::new( ctx, attribute_prototype_id, input.func_argument_id, input_prop_id, ) .await?; } Ok((map_prop_id, attribute_prototype_id)) } }

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