Skip to main content
Glama

Convex MCP server

Official
by get-convex
array.rs4.32 kB
use std::{ fmt, hash::{ Hash, Hasher, }, ops::Deref, }; use errors::ErrorMetadata; use super::size::Size; use crate::{ heap_size::{ HeapSize, WithHeapSize, }, size::{ check_nesting, check_system_size, }, utils::display_sequence, ConvexValue, }; const MAX_ARRAY_LEN: usize = 8192; /// Wrapper on `Vec<Value>` that enforces size limits. #[derive(Clone)] pub struct ConvexArray { // Precomputed `1 + size(v1) + ... + size(vN) + 1` size: usize, // Precomputed `1 + max(nesting(v1), ..., nesting(vN))`. nesting: usize, items: WithHeapSize<Vec<ConvexValue>>, } impl ConvexArray { pub fn empty() -> Self { Self { size: 2, nesting: 1, items: WithHeapSize::default(), } } } impl IntoIterator for ConvexArray { type IntoIter = std::vec::IntoIter<ConvexValue>; type Item = ConvexValue; fn into_iter(self) -> Self::IntoIter { self.items.into_iter() } } impl<'a> IntoIterator for &'a ConvexArray { type IntoIter = std::slice::Iter<'a, ConvexValue>; type Item = &'a ConvexValue; fn into_iter(self) -> Self::IntoIter { self.items.iter() } } impl TryFrom<Vec<ConvexValue>> for ConvexArray { type Error = anyhow::Error; fn try_from(items: Vec<ConvexValue>) -> anyhow::Result<Self> { if items.len() > MAX_ARRAY_LEN { anyhow::bail!(ErrorMetadata::bad_request( "ArrayTooLong", format!( "Array length is too long ({} > maximum length {MAX_ARRAY_LEN})", items.len() ), )); } let size = 1 + items.iter().map(|v| v.size()).sum::<usize>() + 1; check_system_size(size)?; let nesting = 1 + items.iter().map(|v| v.nesting()).max().unwrap_or(0); check_nesting(nesting)?; Ok(Self { size, nesting, items: items.into(), }) } } impl From<ConvexArray> for Vec<ConvexValue> { fn from(array: ConvexArray) -> Self { array.items.into() } } impl Deref for ConvexArray { type Target = [ConvexValue]; fn deref(&self) -> &[ConvexValue] { &self.items[..] } } impl fmt::Debug for ConvexArray { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&self.items, f) } } impl fmt::Display for ConvexArray { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { display_sequence(f, ["[", "]"], self.items.iter()) } } // We only compute the hash on the non-derived state but have an assert in // `PartialEq` to make sure the derived state always matches. impl Hash for ConvexArray { fn hash<H: Hasher>(&self, hasher: &mut H) { self.items.hash(hasher) } } impl PartialEq for ConvexArray { fn eq(&self, other: &Self) -> bool { if self.items == other.items { // We're just comparing based on items but make sure the derived data always // matches. assert_eq!(self.size, other.size); assert_eq!(self.nesting, other.nesting); return true; } false } } impl Eq for ConvexArray {} impl Size for ConvexArray { fn size(&self) -> usize { self.size } fn nesting(&self) -> usize { self.nesting } } impl HeapSize for ConvexArray { fn heap_size(&self) -> usize { self.items.heap_size() } } #[cfg(any(test, feature = "testing"))] impl proptest::arbitrary::Arbitrary for ConvexArray { type Parameters = proptest::collection::SizeRange; type Strategy = impl proptest::strategy::Strategy<Value = ConvexArray>; fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { use proptest::prelude::*; prop::collection::vec(any::<ConvexValue>(), args) .prop_filter_map("Vec wasn't a valid Convex value", |s| { Self::try_from(s).ok() }) } } #[macro_export] /// Create an array. /// /// Uses the same syntax as vec![]. macro_rules! array { () => ( $crate::ConvexArray::empty() ); ($($x:expr),+ $(,)?) => ( $crate::ConvexArray::try_from( vec![$($x),+] ) ); }

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/get-convex/convex-backend'

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