Skip to main content

component_shape/
lib.rs

1//! Framework-neutral component shape metadata and naming utilities.
2//!
3//! `McpInput` describes model-controlled structured input at the metadata
4//! level. Protocol handling and JSON Schema helpers live in `component-shape-mcp`.
5
6mod component_suffix;
7mod field_component;
8mod mcp;
9mod metadata;
10mod rust_syntax;
11mod value_change;
12
13pub use component_suffix::{
14    ComponentSuffix, ComponentSuffixError, component_suffix_from_suffix, is_valid_component_suffix,
15    validate_component_suffix,
16};
17pub use field_component::{ComponentFieldName, ComponentShapeUse};
18pub use mcp::{
19    McpInput, McpInputShape, McpPrimitiveKind, McpRangeBoundKind, McpToolMetadataError,
20    validate_mcp_tool_metadata_text, validate_mcp_tool_name,
21};
22pub use metadata::{
23    ComponentCapabilities, ComponentPrototyping, RenderCapability, ValueBindingCapability,
24};
25pub use rust_syntax::{RustExpr, RustPath, RustSyntaxError, RustSyntaxKind, RustType};
26pub use value_change::ValueChange;
27
28/// Framework-neutral metadata published by a component shape.
29pub trait ComponentShapeMetadata {
30    /// Generator-facing prototyping metadata owned by the shape.
31    const PROTOTYPING: ComponentPrototyping = ComponentPrototyping::new();
32    /// Framework-neutral runtime capabilities published by the shape.
33    const CAPABILITIES: ComponentCapabilities = ComponentCapabilities::new();
34    /// Coarse model-controlled input metadata published by the shape.
35    const MCP_INPUT: McpInput = McpInput::unsupported();
36}
37
38/// Marker for component shapes declared through a trusted declaration surface.
39///
40/// Backend crates implement this for shapes declared by their public macros or
41/// other trusted declaration APIs. Hand-written runtime implementations should
42/// not automatically satisfy this marker unless that backend explicitly accepts
43/// them as declared shapes.
44pub trait DeclaredComponentShape: ComponentShapeMetadata {}
45
46/// Marker that a component shape supports a value or field type.
47///
48/// Backend-specific compatibility traits can extend or pair with this marker
49/// while keeping backend-owned methods and diagnostics on their own traits.
50/// The value-specific MCP input inherits the shape-level MCP input by default,
51/// and declaration macros may emit a more precise value-specific override for
52/// simple JSON-compatible value shapes.
53pub trait ComponentShapeFor<Value>: ComponentShapeMetadata {
54    /// Coarse model-controlled input metadata for this shape/value pair.
55    ///
56    /// This inherits [`ComponentShapeMetadata::MCP_INPUT`] unless the pair
57    /// publishes a more precise value-specific shape.
58    const MCP_INPUT: McpInput = <Self as ComponentShapeMetadata>::MCP_INPUT;
59}
60
61#[cfg(test)]
62mod tests {
63    use super::{
64        ComponentShapeFor, ComponentShapeMetadata, McpInput, McpInputShape, McpPrimitiveKind,
65    };
66
67    struct TextShape;
68
69    impl ComponentShapeMetadata for TextShape {
70        const MCP_INPUT: McpInput = McpInput::string();
71    }
72
73    impl ComponentShapeFor<String> for TextShape {}
74
75    impl ComponentShapeFor<Vec<String>> for TextShape {
76        const MCP_INPUT: McpInput = McpInput::string_list();
77    }
78
79    #[test]
80    fn component_shape_for_inherits_shape_level_mcp_input_by_default() {
81        assert_eq!(
82            <TextShape as ComponentShapeFor<String>>::MCP_INPUT.input_shape(),
83            McpInputShape::Scalar(McpPrimitiveKind::String)
84        );
85    }
86
87    #[test]
88    fn component_shape_for_can_override_value_specific_mcp_input() {
89        assert_eq!(
90            <TextShape as ComponentShapeFor<Vec<String>>>::MCP_INPUT.input_shape(),
91            McpInputShape::List(McpPrimitiveKind::String)
92        );
93    }
94}