chore: add #[non_exhaustive] to remaining public structs (#768)

* chore: add #[non_exhaustive] to remaining public structs

* chore: add #[non_exhaustive] to remaining public types

* chore: enable exhaustive_structs/enums clippy lints

* test: add untagged ServerResult deserialization regression tests
This commit is contained in:
Dale Seo 2026-03-26 10:23:58 -04:00 • committed by GitHub
commit 6a3b32d3ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 430 additions and 211 deletions

View file

@ -138,6 +138,7 @@ where
}
}
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct Extension<T>(pub T);
impl<C, T> FromContextPart<C> for Extension<T>
@ -182,6 +183,7 @@ where
}
}
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct RequestId(pub crate::model::RequestId);
impl<C> FromContextPart<C> for RequestId

View file

@ -20,6 +20,7 @@ use crate::{
};
/// Context for prompt retrieval operations
#[non_exhaustive]
pub struct PromptContext<'a, S> {
pub server: &'a S,
pub name: String,
@ -117,6 +118,7 @@ impl<T: IntoGetPromptResult> IntoGetPromptResult for Result<T, crate::ErrorData>
// Future wrapper that automatically handles IntoGetPromptResult conversion
pin_project_lite::pin_project! {
#[project = IntoGetPromptResultFutProj]
#[non_exhaustive]
pub enum IntoGetPromptResultFut<F, R> {
Pending {
#[pin]
@ -151,6 +153,7 @@ where
}
// Prompt-specific extractor for prompt name
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct PromptName(pub String);
impl<S> FromContextPart<PromptContext<'_, S>> for PromptName {

View file

@ -13,6 +13,7 @@ use crate::{
pub mod prompt;
pub mod tool;
#[non_exhaustive]
pub struct Router<S> {
pub tool_router: tool::ToolRouter<S>,
pub prompt_router: prompt::PromptRouter<S>,

View file

@ -6,6 +6,7 @@ use crate::{
service::{MaybeBoxFuture, MaybeSend},
};
#[non_exhaustive]
pub struct PromptRoute<S> {
#[allow(clippy::type_complexity)]
pub get: Arc<DynGetPromptHandler<S>>,
@ -90,6 +91,7 @@ where
}
/// Adapter for functions generated by the #\[prompt\] macro
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct PromptAttrGenerateFunctionAdapter;
impl<S, F> IntoPromptRoute<S, PromptAttrGenerateFunctionAdapter> for F
@ -103,6 +105,7 @@ where
}
#[derive(Debug)]
#[non_exhaustive]
pub struct PromptRouter<S> {
#[allow(clippy::type_complexity)]
pub map: std::collections::HashMap<Cow<'static, str>, PromptRoute<S>>,

View file

@ -136,6 +136,7 @@ use crate::{
service::{MaybeBoxFuture, MaybeSend},
};
#[non_exhaustive]
pub struct ToolRoute<S> {
#[allow(clippy::type_complexity)]
pub call: Arc<DynCallToolHandler<S>>,
@ -216,6 +217,7 @@ where
}
}
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct ToolAttrGenerateFunctionAdapter;
impl<S, F> IntoToolRoute<S, ToolAttrGenerateFunctionAdapter> for F
where
@ -251,6 +253,7 @@ where
}
}
#[non_exhaustive]
pub struct WithToolAttr<C, S, A>
where
C: CallToolHandler<S, A> + MaybeSend + Clone + 'static,
@ -292,6 +295,7 @@ where
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct ToolRouter<S> {
#[allow(clippy::type_complexity)]
pub map: std::collections::HashMap<Cow<'static, str>, ToolRoute<S>>,

View file

@ -29,6 +29,7 @@ pub fn parse_json_object<T: DeserializeOwned>(input: JsonObject) -> Result<T, cr
)
})
}
#[non_exhaustive]
pub struct ToolCallContext<'s, S> {
pub request_context: RequestContext<RoleServer>,
pub service: &'s S,
@ -104,6 +105,7 @@ impl<T: IntoCallToolResult> IntoCallToolResult for Result<T, crate::ErrorData> {
pin_project_lite::pin_project! {
#[project = IntoCallToolResultFutProj]
#[non_exhaustive]
pub enum IntoCallToolResultFut<F, R> {
Pending {
#[pin]
@ -163,6 +165,7 @@ pub type DynCallToolHandler<S> =
-> futures::future::LocalBoxFuture<'s, Result<CallToolResult, crate::ErrorData>>;
// Tool-specific extractor for tool name
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct ToolName(pub Cow<'static, str>);
impl<S> FromContextPart<ToolCallContext<'_, S>> for ToolName {

View file

@ -14,6 +14,7 @@ use crate::{
/// serialized as structured JSON content with an associated schema.
/// The framework will place the JSON in the `structured_content` field
/// of the tool result rather than the regular `content` field.
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct Json<T>(pub T);
// Implement JsonSchema for Json<T> to delegate to T's schema

View file

@ -42,6 +42,7 @@ use schemars::JsonSchema;
/// - Returns appropriate error responses if deserialization fails
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct Parameters<P>(pub P);
impl<P: JsonSchema> JsonSchema for Parameters<P> {