poem 3.1.8

poem-openapi 5.1.9
This commit is contained in:
Sunli
2025-03-24 09:26:11 +08:00
parent 72a81e7bad
commit d21489fc88
197 changed files with 597 additions and 583 deletions

View File

@@ -23,8 +23,14 @@ jobs:
path: poem-openapi
- name: poem-lambda
path: poem-lambda
- name: poem-grpc-build
path: poem-grpc-build
- name: poem-grpc
path: poem-grpc
- name: poem-mcpserver-macros
path: poem-mcpserver-macros
- name: poem-mcpserver
path: poem-mcpserver
services:
redis:
image: redis:5.0.7

View File

@@ -21,7 +21,7 @@ jobs:
- name: Install Stable Toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.83.0
toolchain: 1.85.0
components: rustfmt
- name: Cache Rust
uses: Swatinem/rust-cache@v2

View File

@@ -36,6 +36,12 @@ jobs:
- name: poem-grpc
registryName: poem-grpc
path: poem-grpc
- name: poem-mcpserver-macros
registryName: poem-mcpserver-macros
path: poem-mcpserver-macros
- name: poem-mcpserver
registryName: poem-mcpserver
path: poem-mcpserver
steps:
- uses: dtolnay/rust-toolchain@stable
with:

View File

@@ -14,19 +14,19 @@ members = [
[workspace.package]
authors = ["sunli <scott_s829@163.com>"]
edition = "2021"
edition = "2024"
license = "MIT OR Apache-2.0"
documentation = "https://docs.rs/poem/"
homepage = "https://github.com/poem-web/poem"
repository = "https://github.com/poem-web/poem"
rust-version = "1.83"
rust-version = "1.85"
[workspace.dependencies]
poem = { path = "poem", version = "3.1.7", default-features = false }
poem-derive = { path = "poem-derive", version = "3.1.4" }
poem-openapi-derive = { path = "poem-openapi-derive", version = "5.1.8" }
poem-grpc-build = { path = "poem-grpc-build", version = "0.5.2" }
poem-mcpserver-macros = { path = "poem-mcpserver-macros", version = "0.1.6" }
poem = { path = "poem", version = "3.1.8", default-features = false }
poem-derive = { path = "poem-derive", version = "3.1.8" }
poem-openapi-derive = { path = "poem-openapi-derive", version = "5.1.9" }
poem-grpc-build = { path = "poem-grpc-build", version = "0.5.4" }
poem-mcpserver-macros = { path = "poem-mcpserver-macros", version = "0.1.7" }
proc-macro-crate = "3.0.0"
proc-macro2 = "1.0.29"

View File

@@ -10,8 +10,8 @@
alt="Unsafe Rust forbidden" />
</a>
<a>
<img src="https://img.shields.io/badge/rustc-1.83.0+-ab6000.svg"
alt="rustc 1.83.0+" />
<img src="https://img.shields.io/badge/rustc-1.85.0+-ab6000.svg"
alt="rustc 1.85.0+" />
</a>
<a href="https://discord.gg/qWWNxwasb7">
<img src="https://img.shields.io/discord/932986985604333638.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2" />

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-derive"
version = "3.1.4"
version = "3.1.8"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -11,7 +11,7 @@ mod utils;
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse_macro_input, FnArg, GenericParam, ItemFn, Member, Result};
use syn::{FnArg, GenericParam, ItemFn, Member, Result, parse_macro_input};
/// Wrap an asynchronous function as an `Endpoint`.
///

View File

@@ -1,5 +1,5 @@
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::{Span, TokenStream};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::quote;
use syn::Ident;

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-grpc-build"
version = "0.5.2"
version = "0.5.4"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -1,5 +1,5 @@
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::{Span, TokenStream};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::quote;
use syn::Ident;

View File

@@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# [0.5.3] 2024-01-04
# [0.5.4] 2025-03-24
- Update MSRV to `1.85.0`
# [0.5.3] 2025-01-04
- feat: Implement enable_type_name config method [#924](https://github.com/poem-web/poem/pull/924)

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-grpc"
version = "0.5.3"
version = "0.5.4"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -21,8 +21,8 @@
alt="Unsafe Rust forbidden" />
</a>
<a>
<img src="https://img.shields.io/badge/rustc-1.83.0+-ab6000.svg"
alt="rustc 1.83.0+" />
<img src="https://img.shields.io/badge/rustc-1.85.0+-ab6000.svg"
alt="rustc 1.85.0+" />
</a>
</div>
@@ -63,7 +63,7 @@ This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in
## MSRV
The minimum supported Rust version for this crate is `1.83.0`.
The minimum supported Rust version for this crate is `1.85.0`.
## Contributing

View File

@@ -5,23 +5,23 @@ use futures_util::TryStreamExt;
use http_body_util::BodyExt;
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
use poem::{
endpoint::{DynEndpoint, ToDynEndpoint},
http::{
header::{self, InvalidHeaderValue},
uri::InvalidUri,
Extensions, HeaderValue, Method, StatusCode, Uri, Version,
},
Endpoint, EndpointExt, IntoEndpoint, Middleware, Request as HttpRequest,
Response as HttpResponse,
endpoint::{DynEndpoint, ToDynEndpoint},
http::{
Extensions, HeaderValue, Method, StatusCode, Uri, Version,
header::{self, InvalidHeaderValue},
uri::InvalidUri,
},
};
use rustls::ClientConfig as TlsClientConfig;
use crate::{
Code, CompressionEncoding, Metadata, Request, Response, Status, Streaming,
codec::Codec,
compression::get_incoming_encodings,
connector::HttpsConnector,
encoding::{create_decode_response_body, create_encode_request_body},
Code, CompressionEncoding, Metadata, Request, Response, Status, Streaming,
};
pub(crate) type BoxBody = http_body_util::combinators::BoxBody<Bytes, IoError>;

View File

@@ -1,11 +1,11 @@
use std::{fmt::Display, str};
use serde::{
Serialize,
ser::{
SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant, Serializer,
},
Serialize,
};
pub(crate) struct I64ToStringSerializer<S>(pub(crate) S);

View File

@@ -4,7 +4,7 @@ use std::{
};
use bytes::{BufMut, BytesMut};
use serde::{de::DeserializeOwned, Serialize};
use serde::{Serialize, de::DeserializeOwned};
use crate::codec::{Codec, Decoder, Encoder};

View File

@@ -165,6 +165,7 @@ fn unimplemented(accept_compressed: &[CompressionEncoding]) -> Status {
.with_message("unsupported encoding")
}
#[allow(clippy::result_large_err)]
pub(crate) fn get_incoming_encodings(
headers: &HeaderMap,
accept_compressed: &[CompressionEncoding],

View File

@@ -5,8 +5,8 @@ use std::{
task::{Context, Poll},
};
use futures_util::{future::BoxFuture, FutureExt};
use http::{uri::Scheme, Uri};
use futures_util::{FutureExt, future::BoxFuture};
use http::{Uri, uri::Scheme};
use hyper::rt::{Read, ReadBufCursor, Write};
use hyper_util::{
client::legacy::connect::{Connected, Connection},
@@ -14,7 +14,7 @@ use hyper_util::{
};
use rustls::{ClientConfig, RootCertStore};
use tokio::net::TcpStream;
use tokio_rustls::{client::TlsStream, TlsConnector};
use tokio_rustls::{TlsConnector, client::TlsStream};
use tower_service::Service;
pub(crate) enum MaybeHttpsStream {

View File

@@ -3,14 +3,14 @@ use std::io::Result as IoResult;
use bytes::{Buf, BufMut, Bytes, BytesMut};
use futures_util::StreamExt;
use http_body_util::{BodyExt, StreamBody};
use hyper::{body::Frame, HeaderMap};
use hyper::{HeaderMap, body::Frame};
use poem::Body;
use sync_wrapper::SyncStream;
use crate::{
Code, CompressionEncoding, Status, Streaming,
client::BoxBody,
codec::{Decoder, Encoder},
Code, CompressionEncoding, Status, Streaming,
};
async fn encode_data_frame<T: Encoder>(
@@ -55,6 +55,7 @@ impl DataFrameDecoder {
}
#[inline]
#[allow(clippy::result_large_err)]
fn check_incomplete(&self) -> Result<(), Status> {
if !self.buf.is_empty() {
return Err(Status::new(Code::Internal).with_message("incomplete request"));
@@ -173,6 +174,7 @@ pub(crate) fn create_encode_request_body<T: Encoder>(
BodyExt::boxed(StreamBody::new(SyncStream::new(stream))).into()
}
#[allow(clippy::result_large_err)]
pub(crate) fn create_decode_response_body<T: Decoder>(
mut decoder: T,
headers: &HeaderMap,

View File

@@ -1,7 +1,7 @@
use std::{collections::HashMap, sync::Mutex};
use futures_util::StreamExt;
use poem::{endpoint::BoxEndpoint, IntoEndpoint};
use poem::{IntoEndpoint, endpoint::BoxEndpoint};
use tokio::sync::watch::{Receiver, Sender};
use crate::{Code, Request, Response, Service, Status, Streaming};

View File

@@ -37,7 +37,7 @@ mod test_harness;
pub use client::{ClientBuilderError, ClientConfig, ClientConfigBuilder};
pub use compression::CompressionEncoding;
pub use health::{health_service, HealthReporter, ServingStatus};
pub use health::{HealthReporter, ServingStatus, health_service};
pub use metadata::Metadata;
pub use reflection::Reflection;
pub use request::Request;

View File

@@ -2,7 +2,7 @@
use std::str::FromStr;
use base64::engine::{general_purpose::STANDARD_NO_PAD, Engine};
use base64::engine::{Engine, general_purpose::STANDARD_NO_PAD};
use http::HeaderName;
use poem::http::{HeaderMap, HeaderValue};

View File

@@ -1,7 +1,7 @@
use std::{collections::HashMap, sync::Arc};
use futures_util::StreamExt;
use poem::{endpoint::BoxEndpoint, IntoEndpoint};
use poem::{IntoEndpoint, endpoint::BoxEndpoint};
use prost::Message;
use prost_types::{DescriptorProto, EnumDescriptorProto, FileDescriptorProto, FileDescriptorSet};
use proto::{
@@ -26,6 +26,7 @@ struct State {
}
impl State {
#[allow(clippy::result_large_err)]
fn file_by_filename(&self, filename: &str) -> Result<MessageResponse, Status> {
match self.files.get(filename) {
None => {
@@ -47,6 +48,7 @@ impl State {
}
}
#[allow(clippy::result_large_err)]
fn symbol_by_name(&self, symbol: &str) -> Result<MessageResponse, Status> {
match self.symbols.get(symbol) {
None => {

View File

@@ -1,4 +1,4 @@
use poem::{endpoint::BoxEndpoint, IntoEndpoint, Response};
use poem::{IntoEndpoint, Response, endpoint::BoxEndpoint};
use crate::Service;

View File

@@ -3,14 +3,14 @@ use http::HeaderValue;
use poem::{Body, Request, Response};
use crate::{
Code, CompressionEncoding, Metadata, Request as GrpcRequest, Response as GrpcResponse, Status,
Streaming,
codec::Codec,
compression::get_incoming_encodings,
encoding::{create_decode_request_body, create_encode_response_body},
service::{
BidirectionalStreamingService, ClientStreamingService, ServerStreamingService, UnaryService,
},
Code, CompressionEncoding, Metadata, Request as GrpcRequest, Response as GrpcResponse, Status,
Streaming,
};
#[doc(hidden)]

View File

@@ -1,6 +1,6 @@
use std::future::Future;
use crate::{status::Status, streaming::Streaming, Request, Response};
use crate::{Request, Response, status::Status, streaming::Streaming};
/// Represent a GRPC service
pub trait Service {

View File

@@ -1,7 +1,7 @@
use std::fmt::Display;
use http::{header::HeaderValue, HeaderMap};
use percent_encoding::{percent_decode_str, percent_encode, AsciiSet, CONTROLS};
use http::{HeaderMap, header::HeaderValue};
use percent_encoding::{AsciiSet, CONTROLS, percent_decode_str, percent_encode};
use crate::Metadata;
@@ -332,6 +332,7 @@ impl Status {
headers
}
#[allow(clippy::result_large_err)]
pub(crate) fn from_headers(headers: &HeaderMap) -> Result<Option<Status>, Status> {
if let Some(value) = headers.get(GRPC_STATUS_HEADER_CODE) {
let code: Code = value

View File

@@ -3,7 +3,7 @@ use std::{
task::{Context, Poll},
};
use futures_util::{stream::BoxStream, Stream, StreamExt};
use futures_util::{Stream, StreamExt, stream::BoxStream};
use crate::Status;

View File

@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# [5.1.2] 2025-03-24
- Update MSRV to `1.85.0`
# [5.1.1] 2024-11-20
- Update MSRV to `1.81.0`

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-lambda"
version = "5.1.1"
version = "5.1.2"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -21,8 +21,8 @@
alt="Unsafe Rust forbidden" />
</a>
<a>
<img src="https://img.shields.io/badge/rustc-1.83.0+-ab6000.svg"
alt="rustc 1.83.0+" />
<img src="https://img.shields.io/badge/rustc-1.85.0+-ab6000.svg"
alt="rustc 1.85.0+" />
</a>
</div>
@@ -49,7 +49,7 @@ This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in
## MSRV
The minimum supported Rust version for this crate is `1.83.0`.
The minimum supported Rust version for this crate is `1.85.0`.
## Contributing

View File

@@ -11,7 +11,7 @@ use std::{io::ErrorKind, ops::Deref, sync::Arc};
pub use lambda_http::lambda_runtime::Error;
use lambda_http::{
lambda_runtime, service_fn, Body as LambdaBody, Request as LambdaRequest, RequestExt,
Body as LambdaBody, Request as LambdaRequest, RequestExt, lambda_runtime, service_fn,
};
use poem::{Body, Endpoint, EndpointExt, FromRequest, IntoEndpoint, Request, RequestBody, Result};
@@ -22,7 +22,7 @@ use poem::{Body, Endpoint, EndpointExt, FromRequest, IntoEndpoint, Request, Requ
/// # Example
///
/// ```
/// use poem::{handler, Request};
/// use poem::{Request, handler};
/// use poem_lambda::Context;
///
/// #[handler]

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-mcpserver-macros"
version = "0.1.6"
version = "0.1.7"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -3,7 +3,7 @@ mod utils;
use darling::FromMeta;
use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemImpl};
use syn::{ItemImpl, parse_macro_input};
macro_rules! parse_nested_meta {
($ty:ty, $args:expr) => {{

View File

@@ -44,15 +44,13 @@ pub(crate) fn generate(_args: ToolsArgs, mut item_impl: ItemImpl) -> Result<Toke
if method.sig.inputs.is_empty() {
return Err(Error::custom("at least one `&self` receiver is required.")
.with_span(&method.sig.ident)
.into());
.with_span(&method.sig.ident));
}
if !matches!(&method.sig.inputs[0], FnArg::Receiver(_)) {
return Err(
Error::custom("the first parameter must be a `&self` receiver.")
.with_span(&method.sig.inputs[0])
.into(),
.with_span(&method.sig.inputs[0]),
);
}
@@ -65,7 +63,7 @@ pub(crate) fn generate(_args: ToolsArgs, mut item_impl: ItemImpl) -> Result<Toke
unreachable!()
};
let Pat::Ident(ident) = &mut *pat.pat else {
return Err(Error::custom("expected ident").with_span(&pat.pat).into());
return Err(Error::custom("expected ident").with_span(&pat.pat));
};
let param_args = parse_mcp_attrs::<ParamArgs>(&pat.attrs)?;

View File

@@ -1,6 +1,6 @@
use darling::{Error, FromMeta};
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::{Span, TokenStream};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::quote;
use syn::{Attribute, Expr, ExprLit, Ident, Lit, Meta};
@@ -45,7 +45,7 @@ where
{
for attr in attrs {
if attr.path().is_ident("mcp") {
return Ok(T::from_meta(&attr.meta)?);
return T::from_meta(&attr.meta);
}
}
Ok(T::default())

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-mcpserver"
version = "0.1.6"
version = "0.1.7"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -21,8 +21,8 @@
alt="Unsafe Rust forbidden" />
</a>
<a>
<img src="https://img.shields.io/badge/rustc-1.83.0+-ab6000.svg"
alt="rustc 1.83.0+" />
<img src="https://img.shields.io/badge/rustc-1.85.0+-ab6000.svg"
alt="rustc 1.85.0+" />
</a>
</div>
@@ -78,7 +78,7 @@ This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in
## MSRV
The minimum supported Rust version for this crate is `1.83.0`.
The minimum supported Rust version for this crate is `1.85.0`.
## Contributing

View File

@@ -96,8 +96,8 @@ pub struct InitializeResponse {
}
mod protocol_version_serde {
use serde::{de::Error as _, Deserialize, Deserializer, Serializer};
use time::{format_description::BorrowedFormatItem, Date};
use serde::{Deserialize, Deserializer, Serializer, de::Error as _};
use time::{Date, format_description::BorrowedFormatItem};
const DESC: &[BorrowedFormatItem] = time::macros::format_description!("[year]-[month]-[day]");

View File

@@ -2,13 +2,13 @@ use serde_json::Value;
use crate::{
protocol::{
JSON_RPC_VERSION, MCP_PROTOCOL_VERSION,
initialize::{
InitializeRequest, InitializeResponse, PromptsCapability, ResourcesCapability,
ServerCapabilities, ServerInfo, ToolsCapability,
},
rpc::{Request, RequestId, Requests, Response},
tool::{ToolsCallRequest, ToolsListResponse},
JSON_RPC_VERSION, MCP_PROTOCOL_VERSION,
},
tool::{NoTools, Tools},
};
@@ -18,6 +18,13 @@ pub struct McpServer<ToolsType = NoTools> {
tools: ToolsType,
}
impl Default for McpServer<NoTools> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl McpServer<NoTools> {
/// Creates a new MCP server.
#[inline]

View File

@@ -9,19 +9,18 @@ use std::{
use pin_project_lite::pin_project;
use poem::{
get, handler,
EndpointExt, IntoEndpoint, IntoResponse, get, handler,
http::StatusCode,
web::{
sse::{Event, SSE},
Data, Json, Query,
sse::{Event, SSE},
},
EndpointExt, IntoEndpoint, IntoResponse,
};
use serde::Deserialize;
use tokio::sync::mpsc::Sender;
use tokio_stream::Stream;
use crate::{protocol::rpc::Request as McpRequest, tool::Tools, McpServer};
use crate::{McpServer, protocol::rpc::Request as McpRequest, tool::Tools};
struct State<ToolsType> {
server_factory: Box<dyn Fn() -> McpServer<ToolsType> + Send + Sync>,

View File

@@ -4,12 +4,12 @@ use serde::Serialize;
use tokio::io::{AsyncBufReadExt, BufReader};
use crate::{
McpServer,
protocol::{
rpc::{Request, Response, RpcError},
JSON_RPC_VERSION,
rpc::{Request, Response, RpcError},
},
tool::Tools,
McpServer,
};
fn print_response(response: impl Serialize) {

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-openapi-derive"
version = "5.1.8"
version = "5.1.9"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -1,9 +1,9 @@
use darling::{util::SpannedValue, FromMeta};
use darling::{FromMeta, util::SpannedValue};
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
use syn::{
ext::IdentExt, visit_mut::VisitMut, Error, Expr, FnArg, ImplItem, ImplItemFn, ItemImpl, Pat,
Path, ReturnType, Type,
Error, Expr, FnArg, ImplItem, ImplItemFn, ItemImpl, Pat, Path, ReturnType, Type, ext::IdentExt,
visit_mut::VisitMut,
};
use crate::{
@@ -13,9 +13,9 @@ use crate::{
error::GeneratorResult,
parameter_style::ParameterStyle,
utils::{
convert_oai_path, get_crate_name, get_description, get_summary_and_description,
optional_literal, optional_literal_string, parse_oai_attrs, remove_description,
remove_oai_attrs, RemoveLifetime,
RemoveLifetime, convert_oai_path, get_crate_name, get_description,
get_summary_and_description, optional_literal, optional_literal_string, parse_oai_attrs,
remove_description, remove_oai_attrs,
},
validators::Validators,
};
@@ -258,7 +258,7 @@ fn generate_operation(
tuple_struct,
"Only single element tuple structs are supported",
)
.into())
.into());
}
},
_ => return Err(Error::new_spanned(pat, "Invalid param definition").into()),
@@ -278,7 +278,7 @@ fn generate_operation(
};
let is_path = match &*arg_ty {
syn::Type::Path(syn::TypePath { qself: _, path }) => {
path.segments.iter().any(|v| v.ident.to_string() == "Path")
path.segments.iter().any(|v| v.ident == "Path")
}
_ => false,
};

View File

@@ -1,4 +1,4 @@
use darling::{util::SpannedValue, FromMeta};
use darling::{FromMeta, util::SpannedValue};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Lit, Path};

View File

@@ -1,14 +1,14 @@
use darling::{
FromDeriveInput, FromVariant,
ast::{Data, Fields},
util::Ignored,
FromDeriveInput, FromVariant,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ext::IdentExt, Attribute, DeriveInput, Error, Path};
use syn::{Attribute, DeriveInput, Error, Path, ext::IdentExt};
use crate::{
common_args::{apply_rename_rule_variant, ExternalDocument, RenameRule},
common_args::{ExternalDocument, RenameRule, apply_rename_rule_variant},
error::GeneratorResult,
utils::{get_crate_name, get_description, optional_literal},
};

View File

@@ -29,7 +29,7 @@ mod parameter_style;
use darling::FromMeta;
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput, ItemImpl, ItemTrait};
use syn::{DeriveInput, ItemImpl, ItemTrait, parse_macro_input};
macro_rules! parse_nested_meta {
($ty:ty, $args:expr) => {{

View File

@@ -1,13 +1,13 @@
use std::str::FromStr;
use darling::{ast::Data, util::Ignored, FromDeriveInput, FromField};
use darling::{FromDeriveInput, FromField, ast::Data, util::Ignored};
use mime as _;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ext::IdentExt, Attribute, DeriveInput, Error, Generics, Type};
use syn::{Attribute, DeriveInput, Error, Generics, Type, ext::IdentExt};
use crate::{
common_args::{apply_rename_rule_field, DefaultValue, RenameRule},
common_args::{DefaultValue, RenameRule, apply_rename_rule_field},
error::GeneratorResult,
utils::{get_crate_name, get_description, optional_literal},
validators::Validators,
@@ -56,7 +56,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(ident, "Multipart can only be applied to an struct.").into(),
)
);
}
};

View File

@@ -1,7 +1,7 @@
use darling::{
FromDeriveInput,
ast::{Data, Style},
util::Ignored,
FromDeriveInput,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
@@ -61,7 +61,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(ident, "NewType can only be applied to an struct.").into(),
)
);
}
};

View File

@@ -1,14 +1,14 @@
use darling::{
FromDeriveInput, FromVariant,
ast::{Data, Fields},
util::Ignored,
FromDeriveInput, FromVariant,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ext::IdentExt, Attribute, DeriveInput, Error};
use syn::{Attribute, DeriveInput, Error, ext::IdentExt};
use crate::{
common_args::{apply_rename_rule_variant, RenameRule},
common_args::{RenameRule, apply_rename_rule_variant},
error::GeneratorResult,
utils::{get_crate_name, get_description, optional_literal},
};
@@ -46,7 +46,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(ident, "OAuthScopes can only be applied to an enum.").into(),
)
);
}
};

View File

@@ -1,14 +1,14 @@
use darling::{
FromDeriveInput, FromField,
ast::Data,
util::{Ignored, SpannedValue},
FromDeriveInput, FromField,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ext::IdentExt, Attribute, DeriveInput, Error, Generics, Path, Type};
use syn::{Attribute, DeriveInput, Error, Generics, Path, Type, ext::IdentExt};
use crate::{
common_args::{apply_rename_rule_field, DefaultValue, ExternalDocument, RenameRule},
common_args::{DefaultValue, ExternalDocument, RenameRule, apply_rename_rule_field},
error::GeneratorResult,
utils::{create_object_name, get_crate_name, get_description, optional_literal},
validators::Validators,

View File

@@ -1,9 +1,9 @@
use std::str::FromStr;
use darling::{
FromDeriveInput, FromVariant,
ast::{Data, Fields},
util::{Ignored, SpannedValue},
FromDeriveInput, FromVariant,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
@@ -44,7 +44,9 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
let e = match &args.data {
Data::Enum(e) => e,
_ => {
return Err(Error::new_spanned(ident, "Request can only be applied to an enum.").into())
return Err(
Error::new_spanned(ident, "Request can only be applied to an enum.").into(),
);
}
};
let description = get_description(&args.attrs)?;
@@ -108,7 +110,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(&variant.ident, "Incorrect request definition.").into(),
)
);
}
}
}

View File

@@ -1,7 +1,7 @@
use darling::{
FromDeriveInput, FromField, FromVariant,
ast::{Data, Fields},
util::Ignored,
FromDeriveInput, FromField, FromVariant,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
@@ -71,7 +71,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(ident, "Response can only be applied to an enum.").into(),
)
);
}
};
@@ -365,7 +365,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(&variant.ident, "Incorrect response definition.").into(),
)
);
}
}
}

View File

@@ -1,7 +1,7 @@
use darling::{
FromDeriveInput, FromVariant,
ast::{Data, Fields},
util::{Ignored, SpannedValue},
FromDeriveInput, FromVariant,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
@@ -44,7 +44,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
ident,
"ResponseContent can only be applied to an enum.",
)
.into())
.into());
}
};
@@ -115,7 +115,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(&variant.ident, "Incorrect request definition.").into(),
)
);
}
}
}

View File

@@ -1,7 +1,7 @@
use darling::{
FromDeriveInput, FromMeta, FromVariant,
ast::{Data, Fields, Style},
util::SpannedValue,
FromDeriveInput, FromMeta, FromVariant,
};
use http::header::HeaderName;
use proc_macro2::{Ident, Span, TokenStream};
@@ -253,7 +253,7 @@ impl SecuritySchemeArgs {
&self.ident,
r#"Missing a key name. #[oai(key_name = "...")]"#,
)
.into())
.into());
}
}

View File

@@ -1,14 +1,14 @@
use darling::{
FromDeriveInput, FromVariant,
ast::{Data, Fields},
util::Ignored,
FromDeriveInput, FromVariant,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ext::IdentExt, Attribute, DeriveInput, Error};
use syn::{Attribute, DeriveInput, Error, ext::IdentExt};
use crate::{
common_args::{apply_rename_rule_variant, ExternalDocument, RenameRule},
common_args::{ExternalDocument, RenameRule, apply_rename_rule_variant},
error::GeneratorResult,
utils::{get_crate_name, get_description, optional_literal},
};

View File

@@ -1,14 +1,14 @@
use darling::{
FromDeriveInput, FromVariant,
ast::{Data, Fields},
util::Ignored,
FromDeriveInput, FromVariant,
};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ext::IdentExt, Attribute, DeriveInput, Error, Generics, Type};
use syn::{Attribute, DeriveInput, Error, Generics, Type, ext::IdentExt};
use crate::{
common_args::{apply_rename_rule_variant, ExternalDocument, RenameRule},
common_args::{ExternalDocument, RenameRule, apply_rename_rule_variant},
error::GeneratorResult,
utils::{create_object_name, get_crate_name, get_description, optional_literal},
};
@@ -190,7 +190,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
_ => {
return Err(
Error::new_spanned(&variant.ident, "Incorrect oneof definition.").into(),
)
);
}
}
}

View File

@@ -1,12 +1,12 @@
use std::collections::HashSet;
use darling::{util::SpannedValue, FromMeta};
use darling::{FromMeta, util::SpannedValue};
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::{Ident, Span, TokenStream};
use proc_macro_crate::{crate_name, FoundCrate};
use quote::quote;
use syn::{
visit_mut, visit_mut::VisitMut, Attribute, Error, Expr, ExprLit, GenericParam, Generics,
Lifetime, Lit, Meta, Result,
Attribute, Error, Expr, ExprLit, GenericParam, Generics, Lifetime, Lit, Meta, Result,
visit_mut, visit_mut::VisitMut,
};
use crate::error::GeneratorResult;

View File

@@ -1,4 +1,4 @@
use darling::{util::SpannedValue, FromMeta};
use darling::{FromMeta, util::SpannedValue};
use proc_macro2::TokenStream;
use quote::quote;
use regex::Regex;

View File

@@ -1,21 +1,21 @@
use std::collections::HashSet;
use darling::{util::SpannedValue, FromMeta};
use darling::{FromMeta, util::SpannedValue};
use indexmap::IndexMap;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
ext::IdentExt, visit_mut::VisitMut, Error, FnArg, ItemTrait, Pat, Path, ReturnType, TraitItem,
TraitItemFn,
Error, FnArg, ItemTrait, Pat, Path, ReturnType, TraitItem, TraitItemFn, ext::IdentExt,
visit_mut::VisitMut,
};
use crate::{
common_args::{APIMethod, DefaultValue, ExternalDocument},
error::GeneratorResult,
utils::{
get_crate_name, get_description, get_summary_and_description, optional_literal,
optional_literal_string, parse_oai_attrs, remove_description, remove_oai_attrs,
RemoveLifetime,
RemoveLifetime, get_crate_name, get_description, get_summary_and_description,
optional_literal, optional_literal_string, parse_oai_attrs, remove_description,
remove_oai_attrs,
},
validators::Validators,
};

View File

@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
#[5.1.7] 2025-03-24
#[5.1.9] 2025-03-24
- fix(openapi): do not use `cookie` feature by default [#986](https://github.com/poem-web/poem/pull/986)
- fix: guard cookie features behind feature toggle [#997](https://github.com/poem-web/poem/pull/997)
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- fix(openapi): exclude style parameter when serializing if none [#989](https://github.com/poem-web/poem/pull/989)
- fix(poem-openapi): handle additional_properties correctly in flatten [#961](https://github.com/poem-web/poem/pull/961)
- fix(poem-openapi-derive): Allow different path param names on same route [#952](https://github.com/poem-web/poem/pull/952)
- Update MSRV to `1.85.0`
#[5.1.6] 2025-02-21

View File

@@ -1,6 +1,6 @@
[package]
name = "poem-openapi"
version = "5.1.8"
version = "5.1.9"
authors.workspace = true
edition.workspace = true
license.workspace = true

View File

@@ -22,8 +22,8 @@
alt="Unsafe Rust forbidden" />
</a>
<a>
<img src="https://img.shields.io/badge/rustc-1.83.0+-ab6000.svg"
alt="rustc 1.83.0+" />
<img src="https://img.shields.io/badge/rustc-1.85.0+-ab6000.svg"
alt="rustc 1.85.0+" />
</a>
<a href="https://discord.gg/qWWNxwasb7">
<img src="https://img.shields.io/discord/932986985604333638.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2" />

View File

@@ -1,6 +1,6 @@
use poem::{
web::headers::{Authorization, HeaderMapExt},
Request, Result,
web::headers::{Authorization, HeaderMapExt},
};
use crate::{auth::BasicAuthorization, error::AuthorizationError};

View File

@@ -1,6 +1,6 @@
use poem::{
web::headers::{Authorization, HeaderMapExt},
Request, Result,
web::headers::{Authorization, HeaderMapExt},
};
use crate::{auth::BearerAuthorization, error::AuthorizationError};

View File

@@ -6,7 +6,7 @@ use std::{
};
use futures_util::FutureExt;
use poem::{endpoint::BoxEndpoint, http::Method, Error, FromRequest, Request, RequestBody, Result};
use poem::{Error, FromRequest, Request, RequestBody, Result, endpoint::BoxEndpoint, http::Method};
use serde::Serialize;
use crate::{

View File

@@ -4,20 +4,20 @@ use std::{
};
use poem::{
endpoint::{make_sync, BoxEndpoint},
Endpoint, EndpointExt, IntoEndpoint, Request, Response, Result, Route, RouteMethod,
endpoint::{BoxEndpoint, make_sync},
};
#[cfg(feature = "cookie")]
use poem::{middleware::CookieJarManager, web::cookie::CookieKey};
use crate::{
OpenApi, Webhook,
base::UrlQuery,
registry::{
Document, MetaContact, MetaExternalDocument, MetaHeader, MetaInfo, MetaLicense,
MetaOperationParam, MetaParamIn, MetaSchemaRef, MetaServer, Registry,
},
types::Type,
OpenApi, Webhook,
};
/// An object representing a Server.
@@ -393,12 +393,12 @@ impl<T, W> OpenApiService<T, W> {
/// Create the OpenAPI Explorer endpoint.
#[must_use]
#[cfg(feature = "openapi-explorer")]
pub fn openapi_explorer(&self) -> impl Endpoint
pub fn openapi_explorer(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,
{
crate::ui::openapi_explorer::create_endpoint(&self.spec())
crate::ui::openapi_explorer::create_endpoint(self.spec())
}
/// Create the OpenAPI Explorer HTML
@@ -414,12 +414,12 @@ impl<T, W> OpenApiService<T, W> {
/// Create the Swagger UI endpoint.
#[must_use]
#[cfg(feature = "swagger-ui")]
pub fn swagger_ui(&self) -> impl Endpoint
pub fn swagger_ui(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,
{
crate::ui::swagger_ui::create_endpoint(&self.spec())
crate::ui::swagger_ui::create_endpoint(self.spec())
}
/// Create the Swagger UI HTML
@@ -435,12 +435,12 @@ impl<T, W> OpenApiService<T, W> {
/// Create the Rapidoc endpoint.
#[must_use]
#[cfg(feature = "rapidoc")]
pub fn rapidoc(&self) -> impl Endpoint
pub fn rapidoc(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,
{
crate::ui::rapidoc::create_endpoint(&self.spec())
crate::ui::rapidoc::create_endpoint(self.spec())
}
/// Create the Rapidoc HTML
@@ -456,12 +456,12 @@ impl<T, W> OpenApiService<T, W> {
/// Create the Redoc endpoint.
#[must_use]
#[cfg(feature = "redoc")]
pub fn redoc(&self) -> impl Endpoint
pub fn redoc(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,
{
crate::ui::redoc::create_endpoint(&self.spec())
crate::ui::redoc::create_endpoint(self.spec())
}
/// Create the Redoc HTML
@@ -478,12 +478,12 @@ impl<T, W> OpenApiService<T, W> {
/// Create the Stoplight Elements endpoint.
#[must_use]
#[cfg(feature = "stoplight-elements")]
pub fn stoplight_elements(&self) -> impl Endpoint
pub fn stoplight_elements(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,
{
crate::ui::stoplight_elements::create_endpoint(&self.spec())
crate::ui::stoplight_elements::create_endpoint(self.spec())
}
/// Create the Stoplight Elements HTML.
@@ -498,7 +498,7 @@ impl<T, W> OpenApiService<T, W> {
}
/// Create an endpoint to serve the open api specification as JSON.
pub fn spec_endpoint(&self) -> impl Endpoint
pub fn spec_endpoint(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,
@@ -512,7 +512,7 @@ impl<T, W> OpenApiService<T, W> {
}
/// Create an endpoint to serve the open api specification as YAML.
pub fn spec_endpoint_yaml(&self) -> impl Endpoint
pub fn spec_endpoint_yaml(&self) -> impl Endpoint + 'static
where
T: OpenApi,
W: Webhook,

View File

@@ -3,10 +3,10 @@ use std::ops::{Deref, DerefMut};
use poem::{Request, RequestBody, Result};
use crate::{
ApiExtractor, ApiExtractorType, ExtractParamOptions,
error::ParseParamError,
registry::{MetaParamIn, MetaSchemaRef, Registry},
types::ParseFromParameter,
ApiExtractor, ApiExtractorType, ExtractParamOptions,
};
/// Represents the parameters passed by the cookie.

View File

@@ -3,10 +3,10 @@ use std::ops::{Deref, DerefMut};
use poem::{Request, RequestBody, Result};
use crate::{
ApiExtractor, ApiExtractorType, ExtractParamOptions,
error::ParseParamError,
registry::{MetaParamIn, MetaSchemaRef, Registry},
types::ParseFromParameter,
ApiExtractor, ApiExtractorType, ExtractParamOptions,
};
/// Represents the parameters passed by the request header.

View File

@@ -3,10 +3,10 @@ use std::ops::{Deref, DerefMut};
use poem::{Request, RequestBody, Result};
use crate::{
ApiExtractor, ApiExtractorType, ExtractParamOptions,
error::ParsePathError,
registry::{MetaParamIn, MetaSchemaRef, Registry},
types::ParseFromParameter,
ApiExtractor, ApiExtractorType, ExtractParamOptions,
};
/// Represents the parameters passed by the URI path.

View File

@@ -3,11 +3,11 @@ use std::ops::{Deref, DerefMut};
use poem::{Request, RequestBody, Result};
use crate::{
ApiExtractor, ApiExtractorType, ExtractParamOptions,
base::UrlQuery,
error::ParseParamError,
registry::{MetaParamIn, MetaSchemaRef, Registry},
types::ParseFromParameter,
ApiExtractor, ApiExtractorType, ExtractParamOptions,
};
/// Represents the parameters passed by the query string.

View File

@@ -1,12 +1,12 @@
use std::fmt::Write;
use poem::{http::header::CONTENT_DISPOSITION, Body, IntoResponse, Response};
use poem::{Body, IntoResponse, Response, http::header::CONTENT_DISPOSITION};
use crate::{
ApiResponse,
payload::{Binary, Payload},
registry::{MetaHeader, MetaMediaType, MetaResponse, MetaResponses, MetaSchemaRef, Registry},
types::Type,
ApiResponse,
};
const CONTENT_DISPOSITION_DESC: &str = "Indicate if the content is expected to be displayed inline in the browser, that is, as a Web page or as part of a Web page, or as an attachment, that is downloaded and saved locally.";

View File

@@ -1,15 +1,15 @@
use std::ops::{Deref, DerefMut};
use base64::engine::{general_purpose::STANDARD, Engine};
use base64::engine::{Engine, general_purpose::STANDARD};
use bytes::Bytes;
use futures_util::TryFutureExt;
use poem::{IntoResponse, Request, RequestBody, Response, Result};
use crate::{
ApiResponse,
error::ParseRequestPayloadError,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchema, MetaSchemaRef, Registry},
ApiResponse,
};
/// A binary payload encoded with `base64`.
@@ -18,14 +18,14 @@ use crate::{
///
/// ```rust
/// use poem::{
/// Body, IntoEndpoint, Request, Result,
/// error::BadRequest,
/// http::{Method, StatusCode, Uri},
/// test::TestClient,
/// Body, IntoEndpoint, Request, Result,
/// };
/// use poem_openapi::{
/// payload::{Base64, Json},
/// OpenApi, OpenApiService,
/// payload::{Base64, Json},
/// };
/// use tokio::{io::AsyncReadExt, sync::Mutex};
///

View File

@@ -4,9 +4,9 @@ use bytes::Bytes;
use poem::{Body, FromRequest, IntoResponse, Request, RequestBody, Response, Result};
use crate::{
ApiResponse,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchema, MetaSchemaRef, Registry},
ApiResponse,
};
/// A binary payload.
@@ -15,14 +15,14 @@ use crate::{
///
/// ```rust
/// use poem::{
/// Body, IntoEndpoint, Request, Result,
/// error::BadRequest,
/// http::{Method, StatusCode, Uri},
/// test::TestClient,
/// Body, IntoEndpoint, Request, Result,
/// };
/// use poem_openapi::{
/// payload::{Binary, Json},
/// OpenApi, OpenApiService,
/// payload::{Binary, Json},
/// };
/// use tokio::io::AsyncReadExt;
///

View File

@@ -2,15 +2,15 @@ use std::time::Duration;
use futures_util::{Stream, StreamExt};
use poem::{
web::sse::{Event, SSE},
IntoResponse, Response,
web::sse::{Event, SSE},
};
use crate::{
ApiResponse,
payload::Payload,
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchema, MetaSchemaRef, Registry},
types::{ToJSON, Type},
ApiResponse,
};
type ToEventFn<T> = Box<dyn (FnMut(T) -> Event) + Send + 'static>;
@@ -49,7 +49,7 @@ impl<T: Stream + Send + 'static> EventStream<T> {
///
/// ```rust
/// use poem::web::sse::Event;
/// use poem_openapi::{payload::EventStream, types::ToJSON, Object};
/// use poem_openapi::{Object, payload::EventStream, types::ToJSON};
///
/// #[derive(Debug, Object)]
/// struct MyEvent {

View File

@@ -3,10 +3,10 @@ use std::ops::{Deref, DerefMut};
use poem::{FromRequest, IntoResponse, Request, RequestBody, Response, Result};
use crate::{
ApiResponse,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchemaRef, Registry},
types::Type,
ApiResponse,
};
/// A UTF8 html payload.

View File

@@ -4,11 +4,11 @@ use poem::{FromRequest, IntoResponse, Request, RequestBody, Response, Result};
use serde_json::Value;
use crate::{
ApiResponse,
error::ParseRequestPayloadError,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchemaRef, Registry},
types::{ParseFromJSON, ToJSON, Type},
ApiResponse,
};
/// A JSON payload.

View File

@@ -3,10 +3,10 @@ use std::ops::{Deref, DerefMut};
use poem::{FromRequest, IntoResponse, Request, RequestBody, Response, Result};
use crate::{
ApiResponse,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchemaRef, Registry},
types::Type,
ApiResponse,
};
/// A UTF8 string payload.

View File

@@ -1,11 +1,11 @@
use poem::{
http::{header::HeaderName, HeaderMap, HeaderValue, StatusCode},
Error, IntoResponse,
http::{HeaderMap, HeaderValue, StatusCode, header::HeaderName},
};
use crate::{
registry::{MetaResponses, Registry},
ApiResponse,
registry::{MetaResponses, Registry},
};
/// A response type wrapper.
@@ -16,14 +16,14 @@ use crate::{
///
/// ```
/// use poem::{
/// Body, IntoEndpoint, Request, Result,
/// error::BadRequest,
/// http::{Method, StatusCode, Uri},
/// test::TestClient,
/// Body, IntoEndpoint, Request, Result,
/// };
/// use poem_openapi::{
/// payload::{Json, Response},
/// OpenApi, OpenApiService,
/// payload::{Json, Response},
/// };
/// use tokio::io::AsyncReadExt;
///

View File

@@ -4,11 +4,11 @@ use poem::{FromRequest, IntoResponse, Request, RequestBody, Response, Result};
use serde_json::Value;
use crate::{
ApiResponse,
error::ParseRequestPayloadError,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchemaRef, Registry},
types::{ParseFromXML, ToXML, Type},
ApiResponse,
};
/// A XML payload.

View File

@@ -4,11 +4,11 @@ use poem::{FromRequest, IntoResponse, Request, RequestBody, Response, Result};
use serde_json::Value;
use crate::{
ApiResponse,
error::ParseRequestPayloadError,
payload::{ParsePayload, Payload},
registry::{MetaMediaType, MetaResponse, MetaResponses, MetaSchemaRef, Registry},
types::{ParseFromYAML, ToYAML, Type},
ApiResponse,
};
/// A YAML payload.

View File

@@ -9,10 +9,10 @@ use std::{
use poem::http::Method;
pub(crate) use ser::Document;
use serde::{ser::SerializeMap, Serialize, Serializer};
use serde::{Serialize, Serializer, ser::SerializeMap};
use serde_json::Value;
use crate::{types::Type, ParameterStyle};
use crate::{ParameterStyle, types::Type};
#[allow(clippy::trivially_copy_pass_by_ref)]
#[inline]

View File

@@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use serde::{ser::SerializeMap, Serialize, Serializer};
use serde::{Serialize, Serializer, ser::SerializeMap};
use crate::registry::{
MetaApi, MetaExternalDocument, MetaInfo, MetaPath, MetaResponses, MetaSchema, MetaSchemaRef,
@@ -58,7 +58,7 @@ impl Serialize for MetaResponses {
match resp.status {
Some(status) => s.serialize_entry(&format!("{status}"), resp)?,
None => match &resp.status_range {
Some(status_range) => s.serialize_entry(&format!("{status_range}"), resp)?,
Some(status_range) => s.serialize_entry(status_range, resp)?,
None => s.serialize_entry("default", resp)?,
},
}

View File

@@ -1,10 +1,10 @@
use poem::{web::StaticFileResponse, Body};
use poem::{Body, web::StaticFileResponse};
use crate::{
ApiResponse,
payload::{Binary, Payload},
registry::{MetaHeader, MetaMediaType, MetaResponse, MetaResponses, Registry},
types::Type,
ApiResponse,
};
const ETAG_DESCRIPTION: &str = r#"The ETag (or entity tag) HTTP response header is an identifier for a specific version of a resource. It lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content was not changed. Additionally, etags help to prevent simultaneous updates of a resource from overwriting each other ("mid-air collisions")."#;
@@ -23,25 +23,29 @@ impl ApiResponse for StaticFileResponse {
content_type: Binary::<Body>::CONTENT_TYPE,
schema: Binary::<Body>::schema_ref(),
}],
headers: vec![MetaHeader {
name: "etag".to_string(),
description: Some(ETAG_DESCRIPTION.to_string()),
required: false,
deprecated: false,
schema: String::schema_ref(),
}, MetaHeader {
name: "last-modified".to_string(),
description: Some(LAST_MODIFIED_DESCRIPTION.to_string()),
required: false,
deprecated: false,
schema: String::schema_ref(),
}, MetaHeader {
name: "content-type".to_string(),
description: Some(CONTENT_TYPE_DESCRIPTION.to_string()),
required: false,
deprecated: false,
schema: String::schema_ref(),
}],
headers: vec![
MetaHeader {
name: "etag".to_string(),
description: Some(ETAG_DESCRIPTION.to_string()),
required: false,
deprecated: false,
schema: String::schema_ref(),
},
MetaHeader {
name: "last-modified".to_string(),
description: Some(LAST_MODIFIED_DESCRIPTION.to_string()),
required: false,
deprecated: false,
schema: String::schema_ref(),
},
MetaHeader {
name: "content-type".to_string(),
description: Some(CONTENT_TYPE_DESCRIPTION.to_string()),
required: false,
deprecated: false,
schema: String::schema_ref(),
},
],
},
MetaResponse {
description: "Not modified",
@@ -77,7 +81,8 @@ impl ApiResponse for StaticFileResponse {
status_range: None,
content: vec![],
headers: vec![],
}, MetaResponse {
},
MetaResponse {
description: "Internal server error",
status: Some(500),
status_range: None,

View File

@@ -1,6 +1,6 @@
use std::borrow::Cow;
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize, Serializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned};
use serde_json::Value;
use crate::{

View File

@@ -3,7 +3,7 @@ use std::{
ops::{Deref, DerefMut},
};
use base64::engine::{general_purpose::STANDARD, Engine};
use base64::engine::{Engine, general_purpose::STANDARD};
use bytes::Bytes;
use serde_json::Value;

View File

@@ -3,8 +3,8 @@ use std::borrow::Cow;
use poem::web::Field;
use serde_json::Value;
use time::{
format_description::well_known::Rfc3339, macros::format_description, Date, OffsetDateTime,
PrimitiveDateTime, Time,
Date, OffsetDateTime, PrimitiveDateTime, Time, format_description::well_known::Rfc3339,
macros::format_description,
};
use crate::{

View File

@@ -1,4 +1,4 @@
use poem::{endpoint::make_sync, web::Html, Endpoint};
use poem::{Endpoint, endpoint::make_sync, web::Html};
const REDOC_JS: &str = include_str!("openapi-explorer.min.js");
@@ -36,7 +36,7 @@ pub(crate) fn create_html(document: &str) -> String {
.replace("{:spec}", document)
}
pub(crate) fn create_endpoint(document: &str) -> impl Endpoint {
let ui_html = create_html(document);
pub(crate) fn create_endpoint(document: String) -> impl Endpoint + 'static {
let ui_html = create_html(&document);
poem::Route::new().at("/", make_sync(move |_| Html(ui_html.clone())))
}

View File

@@ -1,4 +1,4 @@
use poem::{endpoint::make_sync, web::Html, Endpoint};
use poem::{Endpoint, endpoint::make_sync, web::Html};
const RAPIDOC_JS: &str = include_str!("rapidoc-min.js");
const OAUTH_RECEIVER_HTML: &str = include_str!("oauth-receiver.html");
@@ -45,8 +45,8 @@ pub(crate) fn create_html(document: &str) -> String {
.replace("{:spec}", document)
}
pub(crate) fn create_endpoint(document: &str) -> impl Endpoint {
let ui_html = create_html(document);
pub(crate) fn create_endpoint(document: String) -> impl Endpoint {
let ui_html = create_html(&document);
let oauth_receiver_html = OAUTH_RECEIVER_HTML.replace("{:script}", RAPIDOC_JS);
poem::Route::new()

View File

@@ -1,4 +1,4 @@
use poem::{endpoint::make_sync, web::Html, Endpoint};
use poem::{Endpoint, endpoint::make_sync, web::Html};
const REDOC_JS: &str = include_str!("redoc.standalone.js");
@@ -42,7 +42,7 @@ pub(crate) fn create_html(document: &str) -> String {
.replace("{:spec}", document)
}
pub(crate) fn create_endpoint(document: &str) -> impl Endpoint {
let ui_html = create_html(document);
pub(crate) fn create_endpoint(document: String) -> impl Endpoint {
let ui_html = create_html(&document);
poem::Route::new().at("/", make_sync(move |_| Html(ui_html.clone())))
}

View File

@@ -1,4 +1,4 @@
use poem::{endpoint::make_sync, web::Html, Endpoint};
use poem::{Endpoint, endpoint::make_sync, web::Html};
const TEMPLATE: &str = include_str!("stoplight-elements.html");
@@ -6,7 +6,7 @@ pub(crate) fn create_html(document: &str) -> String {
TEMPLATE.replace("'{:spec}'", document)
}
pub(crate) fn create_endpoint(document: &str) -> impl Endpoint {
let ui_html = create_html(document);
pub(crate) fn create_endpoint(document: String) -> impl Endpoint {
let ui_html = create_html(&document);
poem::Route::new().at("/", make_sync(move |_| Html(ui_html.clone())))
}

View File

@@ -1,4 +1,4 @@
use poem::{endpoint::make_sync, web::Html, Endpoint};
use poem::{Endpoint, endpoint::make_sync, web::Html};
const SWAGGER_UI_JS: &str = include_str!("swagger-ui-bundle.js");
const SWAGGER_UI_CSS: &str = include_str!("swagger-ui.css");
@@ -50,8 +50,8 @@ pub(crate) fn create_html(document: &str) -> String {
.replace("{:spec}", document)
}
pub(crate) fn create_endpoint(document: &str) -> impl Endpoint {
let ui_html = create_html(document);
pub(crate) fn create_endpoint(document: String) -> impl Endpoint {
let ui_html = create_html(&document);
poem::Route::new()
.at("/", make_sync(move |_| Html(ui_html.clone())))
.at(

View File

@@ -1,15 +1,15 @@
use poem::{
Endpoint, EndpointExt, Error,
http::{Method, StatusCode},
test::TestClient,
web::Data,
Endpoint, EndpointExt, Error,
};
use poem_openapi::{
ApiRequest, ApiResponse, Object, OpenApi, OpenApiService, ParameterStyle, Tags,
param::{Path, Query},
payload::{Binary, Json, Payload, PlainText},
registry::{MetaApi, MetaExternalDocument, MetaOperation, MetaParamIn, MetaSchema, Registry},
types::Type,
ApiRequest, ApiResponse, Object, OpenApi, OpenApiService, ParameterStyle, Tags,
};
#[tokio::test]

View File

@@ -1,9 +1,9 @@
use poem_openapi::{
Enum,
registry::{MetaExternalDocument, MetaSchemaRef, Registry},
types::{ParseFromJSON, ToJSON, Type},
Enum,
};
use serde_json::{json, Value};
use serde_json::{Value, json};
#[test]
fn meta_enum_items() {

View File

@@ -2,13 +2,13 @@ use std::io::Write;
use poem::{Request, RequestBody};
use poem_openapi::{
Enum, Multipart, Object,
payload::{ParsePayload, Payload},
registry::{MetaSchema, MetaSchemaRef},
types::{
multipart::{JsonField, Upload},
Binary,
multipart::{JsonField, Upload},
},
Enum, Multipart, Object,
};
use tokio::io::{AsyncReadExt, AsyncSeekExt};

View File

@@ -1,6 +1,6 @@
use poem_openapi::{
types::{Example, ParseFromJSON, ParseFromMultipartField, ParseFromParameter, ToJSON, Type},
NewType,
types::{Example, ParseFromJSON, ParseFromMultipartField, ParseFromParameter, ToJSON, Type},
};
#[tokio::test]

View File

@@ -1,9 +1,9 @@
use std::collections::HashMap;
use poem_openapi::{
Enum, NewType, Object, OpenApi,
registry::{MetaExternalDocument, MetaSchema, MetaSchemaRef, Registry},
types::{Example, ParseFromJSON, ToJSON, Type},
Enum, NewType, Object, OpenApi,
};
use serde_json::json;

View File

@@ -7,10 +7,10 @@ use poem::{
#[cfg(feature = "cookie")]
use poem_openapi::param::{Cookie as ParamCookie, CookiePrivate, CookieSigned};
use poem_openapi::{
OpenApi, OpenApiService,
param::{Header, Path, Query},
registry::{MetaApi, MetaParamIn, MetaSchema, MetaSchemaRef},
types::Type,
OpenApi, OpenApiService,
};
use serde_json::json;

View File

@@ -1,8 +1,8 @@
use poem::{http::StatusCode, test::TestClient, Error};
use poem::{Error, http::StatusCode, test::TestClient};
use poem_openapi::{
ApiResponse, OpenApi, OpenApiService,
param::Query,
payload::{Json, Response},
ApiResponse, OpenApi, OpenApiService,
};
#[tokio::test]

View File

@@ -1,14 +1,14 @@
use poem::{
Error,
http::{Method, StatusCode},
test::TestClient,
Error,
};
use poem_openapi::{
ApiResponse, OpenApi, OpenApiService,
param::Query,
payload::{Json, PlainText},
registry::MetaApi,
types::{MaybeUndefined, ToJSON},
ApiResponse, OpenApi, OpenApiService,
};
use serde_json::Value;

Some files were not shown because too many files have changed in this diff Show More