From 50e0dcc6c93cd07b96a3df18e8322606ee5b24bb Mon Sep 17 00:00:00 2001 From: Till Rohrmann Date: Wed, 17 Dec 2025 11:02:36 +0100 Subject: [PATCH] Bump Rust edition to 2024 and MSRV to 1.85 Important, we need to release these changes with a new minor release. --- Cargo.toml | 4 ++-- examples/tracing.rs | 2 +- macros/Cargo.toml | 3 ++- macros/src/ast.rs | 16 +++++++++------- macros/src/{gen.rs => generator.rs} | 4 ++-- macros/src/lib.rs | 4 ++-- rust-toolchain.toml | 2 +- src/context/mod.rs | 20 ++++++++++---------- src/context/select.rs | 3 ++- src/endpoint/context.rs | 6 +++--- src/endpoint/futures/async_result_poll.rs | 8 ++++---- src/endpoint/futures/durable_future_impl.rs | 2 +- src/endpoint/futures/handler_state_aware.rs | 4 +++- src/endpoint/futures/intercept_error.rs | 2 +- src/endpoint/futures/select_poll.rs | 6 +++--- src/endpoint/mod.rs | 16 ++++++++++------ src/filter.rs | 4 ++-- src/hyper.rs | 2 +- src/lambda.rs | 2 +- test-services/Cargo.toml | 3 ++- test-services/Dockerfile | 2 +- test-services/src/failing.rs | 4 ++-- test-services/src/proxy.rs | 2 +- test-services/src/test_utils_service.rs | 4 ++-- testcontainers/Cargo.toml | 4 ++-- testcontainers/src/lib.rs | 12 +++++++++--- 26 files changed, 79 insertions(+), 62 deletions(-) rename macros/src/{gen.rs => generator.rs} (99%) diff --git a/Cargo.toml b/Cargo.toml index cc24e58..6137324 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "restate-sdk" version = "0.7.0" -edition = "2021" +edition = "2024" description = "Restate SDK for Rust" license = "MIT" repository = "https://github.com/restatedev/sdk-rust" -rust-version = "1.76.0" +rust-version = "1.85.0" [[example]] name = "tracing" diff --git a/examples/tracing.rs b/examples/tracing.rs index 19f6995..e96de32 100644 --- a/examples/tracing.rs +++ b/examples/tracing.rs @@ -1,7 +1,7 @@ use restate_sdk::prelude::*; use std::time::Duration; use tracing::info; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer}; +use tracing_subscriber::{Layer, layer::SubscriberExt, util::SubscriberInitExt}; #[restate_sdk::service] trait Greeter { diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 1115cab..7049d4a 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "restate-sdk-macros" version = "0.7.0" -edition = "2021" +edition = "2024" description = "Restate SDK for Rust macros" license = "MIT" repository = "https://github.com/restatedev/sdk-rust" +rust-version = "1.85.0" [lib] proc-macro = true diff --git a/macros/src/ast.rs b/macros/src/ast.rs index 7a9aadf..af1d0a0 100644 --- a/macros/src/ast.rs +++ b/macros/src/ast.rs @@ -16,8 +16,8 @@ use syn::parse::{Parse, ParseStream}; use syn::spanned::Spanned; use syn::token::Comma; use syn::{ - braced, parenthesized, parse_quote, Attribute, Error, Expr, ExprLit, FnArg, GenericArgument, - Ident, Lit, Pat, PatType, Path, PathArguments, Result, ReturnType, Token, Type, Visibility, + Attribute, Error, Expr, ExprLit, FnArg, GenericArgument, Ident, Lit, Pat, PatType, Path, + PathArguments, Result, ReturnType, Token, Type, Visibility, braced, parenthesized, parse_quote, }; /// Accumulates multiple errors into a result. @@ -194,10 +194,12 @@ impl Parse for Handler { input.parse::()?; let (ok_ty, err_ty) = match &return_type { - ReturnType::Default => return Err(Error::new( - return_type.span(), - "The return type cannot be empty, only Result or restate_sdk::prelude::HandlerResult is supported as return type", - )), + ReturnType::Default => { + return Err(Error::new( + return_type.span(), + "The return type cannot be empty, only Result or restate_sdk::prelude::HandlerResult is supported as return type", + )); + } ReturnType::Type(_, ty) => { if let Some((ok_ty, err_ty)) = extract_handler_result_parameter(ty) { (ok_ty, err_ty) @@ -251,7 +253,7 @@ fn read_literal_attribute_name(attr: &Attribute) -> Result> { .filter(|val| val.path.require_ident().is_ok_and(|i| i == "name")) .map(|val| { if let Expr::Lit(ExprLit { - lit: Lit::Str(ref literal), + lit: Lit::Str(literal), .. }) = &val.value { diff --git a/macros/src/gen.rs b/macros/src/generator.rs similarity index 99% rename from macros/src/gen.rs rename to macros/src/generator.rs index 22e97e6..3e06598 100644 --- a/macros/src/gen.rs +++ b/macros/src/generator.rs @@ -1,7 +1,7 @@ use crate::ast::{Handler, Object, Service, ServiceInner, ServiceType, Workflow}; use proc_macro2::TokenStream as TokenStream2; use proc_macro2::{Ident, Literal}; -use quote::{format_ident, quote, ToTokens}; +use quote::{ToTokens, format_ident, quote}; use syn::{Attribute, PatType, Visibility}; pub(crate) struct ServiceGenerator<'a> { @@ -386,7 +386,7 @@ impl<'a> ServiceGenerator<'a> { } } -impl<'a> ToTokens for ServiceGenerator<'a> { +impl ToTokens for ServiceGenerator<'_> { fn to_tokens(&self, output: &mut TokenStream2) { output.extend(vec![ self.trait_service(), diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 8290af3..e0fbd08 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -14,10 +14,10 @@ extern crate proc_macro; mod ast; -mod gen; +mod generator; use crate::ast::{Object, Service, Workflow}; -use crate::gen::ServiceGenerator; +use crate::generator::ServiceGenerator; use proc_macro::TokenStream; use quote::ToTokens; use syn::parse_macro_input; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 812fd68..dd94bb9 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.82.0" +channel = "1.85.0" profile = "minimal" components = ["rustfmt", "clippy"] diff --git a/src/context/mod.rs b/src/context/mod.rs index d9b66fd..b6f9076 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -26,7 +26,7 @@ pub struct Context<'ctx> { inner: &'ctx ContextInternal, } -impl<'ctx> Context<'ctx> { +impl Context<'_> { /// Get request headers. pub fn headers(&self) -> &HeaderMap { &self.headers @@ -60,7 +60,7 @@ pub struct SharedObjectContext<'ctx> { pub(crate) inner: &'ctx ContextInternal, } -impl<'ctx> SharedObjectContext<'ctx> { +impl SharedObjectContext<'_> { /// Get object key. pub fn key(&self) -> &str { &self.key @@ -100,7 +100,7 @@ pub struct ObjectContext<'ctx> { pub(crate) inner: &'ctx ContextInternal, } -impl<'ctx> ObjectContext<'ctx> { +impl ObjectContext<'_> { /// Get object key. pub fn key(&self) -> &str { &self.key @@ -153,7 +153,7 @@ impl<'ctx> From<(&'ctx ContextInternal, InputMetadata)> for SharedWorkflowContex } } -impl<'ctx> SharedWorkflowContext<'ctx> { +impl SharedWorkflowContext<'_> { /// Get workflow key. pub fn key(&self) -> &str { &self.key @@ -193,7 +193,7 @@ impl<'ctx> From<(&'ctx ContextInternal, InputMetadata)> for WorkflowContext<'ctx } } -impl<'ctx> WorkflowContext<'ctx> { +impl WorkflowContext<'_> { /// Get workflow key. pub fn key(&self) -> &str { &self.key @@ -752,7 +752,7 @@ pub trait ContextSideEffects<'ctx>: private::SealedContext<'ctx> { /// # use restate_sdk::prelude::*; /// # use rand::Rng; /// async fn rand_generate(mut ctx: Context<'_>) { - /// let x: u32 = ctx.rand().gen(); + /// let x: u32 = ctx.rand().random(); /// # } /// ``` /// @@ -832,13 +832,13 @@ pub trait ContextReadState<'ctx>: private::SealedContext<'ctx> { /// Get state fn get( &self, - key: &str, + key: &'ctx str, ) -> impl Future, TerminalError>> + 'ctx { self.inner_context().get(key) } /// Get state keys - fn get_keys(&self) -> impl Future, TerminalError>> + 'ctx { + fn get_keys(&'ctx self) -> impl Future, TerminalError>> + 'ctx { self.inner_context().get_keys() } } @@ -923,7 +923,7 @@ pub trait ContextPromises<'ctx>: private::SealedContext<'ctx> { /// Create a promise fn promise( &'ctx self, - key: &str, + key: &'ctx str, ) -> impl DurableFuture> + 'ctx { self.inner_context().promise(key) } @@ -931,7 +931,7 @@ pub trait ContextPromises<'ctx>: private::SealedContext<'ctx> { /// Peek a promise fn peek_promise( &self, - key: &str, + key: &'ctx str, ) -> impl Future, TerminalError>> + 'ctx { self.inner_context().peek_promise(key) } diff --git a/src/context/select.rs b/src/context/select.rs index f66dec8..a4891ce 100644 --- a/src/context/select.rs +++ b/src/context/select.rs @@ -76,7 +76,8 @@ macro_rules! select { let handles = vec![$( $crate::count_field!(futures_init.$($skip)*).handle() ,)+]; - let select_fut = futures_init.0.inner_context().select(handles); + let inner_context = futures_init.0.inner_context(); + let select_fut = inner_context.select(handles); match select_fut.await { $( diff --git a/src/endpoint/context.rs b/src/endpoint/context.rs index e83ebab..6de0673 100644 --- a/src/endpoint/context.rs +++ b/src/endpoint/context.rs @@ -16,16 +16,16 @@ use futures::{FutureExt, TryFutureExt}; use pin_project_lite::pin_project; use restate_sdk_shared_core::{ CoreVM, DoProgressResponse, Error as CoreError, Header, NonEmptyValue, NotificationHandle, - RetryPolicy, RunExitResult, TakeOutputResult, Target, TerminalFailure, Value, VM, + RetryPolicy, RunExitResult, TakeOutputResult, Target, TerminalFailure, VM, Value, }; use std::borrow::Cow; use std::collections::HashMap; -use std::future::{ready, Future}; +use std::future::{Future, ready}; use std::marker::PhantomData; use std::mem; use std::pin::Pin; use std::sync::{Arc, Mutex}; -use std::task::{ready, Context, Poll}; +use std::task::{Context, Poll, ready}; use std::time::{Duration, Instant, SystemTime}; pub struct ContextInternalInner { diff --git a/src/endpoint/futures/async_result_poll.rs b/src/endpoint/futures/async_result_poll.rs index 6d84abb..b3ac160 100644 --- a/src/endpoint/futures/async_result_poll.rs +++ b/src/endpoint/futures/async_result_poll.rs @@ -1,8 +1,8 @@ -use crate::endpoint::context::ContextInternalInner; use crate::endpoint::ErrorInner; +use crate::endpoint::context::ContextInternalInner; use restate_sdk_shared_core::{ DoProgressResponse, Error as CoreError, NotificationHandle, TakeOutputResult, TerminalFailure, - Value, VM, + VM, Value, }; use std::future::Future; use std::pin::Pin; @@ -64,7 +64,7 @@ impl Future for VmAsyncResultPollFuture { } } TakeOutputResult::EOF => { - return Poll::Ready(Err(ErrorInner::UnexpectedOutputClosed)) + return Poll::Ready(Err(ErrorInner::UnexpectedOutputClosed)); } } @@ -121,7 +121,7 @@ impl Future for VmAsyncResultPollFuture { return Poll::Ready(Ok(Value::Failure(TerminalFailure { code: 409, message: "cancelled".to_string(), - }))) + }))); } Err(e) => { return Poll::Ready(Err(e.into())); diff --git a/src/endpoint/futures/durable_future_impl.rs b/src/endpoint/futures/durable_future_impl.rs index 7e5881a..fd3b44b 100644 --- a/src/endpoint/futures/durable_future_impl.rs +++ b/src/endpoint/futures/durable_future_impl.rs @@ -4,7 +4,7 @@ use pin_project_lite::pin_project; use restate_sdk_shared_core::NotificationHandle; use std::future::Future; use std::pin::Pin; -use std::task::{ready, Context, Poll}; +use std::task::{Context, Poll, ready}; pin_project! { /// Future that intercepts errors of inner future, and passes them to ContextInternal diff --git a/src/endpoint/futures/handler_state_aware.rs b/src/endpoint/futures/handler_state_aware.rs index 4ed225f..7a1f255 100644 --- a/src/endpoint/futures/handler_state_aware.rs +++ b/src/endpoint/futures/handler_state_aware.rs @@ -58,7 +58,9 @@ where Poll::Pending => Poll::Pending, }, Err(oneshot::error::TryRecvError::Closed) => { - panic!("This is unexpected, this future is still being polled although the sender side was dropped. This should not be possible, because the sender is dropped when this future returns Poll:ready().") + panic!( + "This is unexpected, this future is still being polled although the sender side was dropped. This should not be possible, because the sender is dropped when this future returns Poll:ready()." + ) } } } diff --git a/src/endpoint/futures/intercept_error.rs b/src/endpoint/futures/intercept_error.rs index 81eafe5..d845d5d 100644 --- a/src/endpoint/futures/intercept_error.rs +++ b/src/endpoint/futures/intercept_error.rs @@ -4,7 +4,7 @@ use crate::errors::TerminalError; use pin_project_lite::pin_project; use std::future::Future; use std::pin::Pin; -use std::task::{ready, Context, Poll}; +use std::task::{Context, Poll, ready}; pin_project! { /// Future that intercepts errors of inner future, and passes them to ContextInternal diff --git a/src/endpoint/futures/select_poll.rs b/src/endpoint/futures/select_poll.rs index 2732e24..94e9b99 100644 --- a/src/endpoint/futures/select_poll.rs +++ b/src/endpoint/futures/select_poll.rs @@ -1,5 +1,5 @@ -use crate::endpoint::context::ContextInternalInner; use crate::endpoint::ErrorInner; +use crate::endpoint::context::ContextInternalInner; use crate::errors::TerminalError; use restate_sdk_shared_core::{ DoProgressResponse, Error as CoreError, NotificationHandle, TakeOutputResult, TerminalFailure, @@ -65,7 +65,7 @@ impl Future for VmSelectAsyncResultPollFuture { } } TakeOutputResult::EOF => { - return Poll::Ready(Err(ErrorInner::UnexpectedOutputClosed)) + return Poll::Ready(Err(ErrorInner::UnexpectedOutputClosed)); } } @@ -125,7 +125,7 @@ impl Future for VmSelectAsyncResultPollFuture { code: 409, message: "cancelled".to_string(), } - .into()))) + .into()))); } Err(e) => { return Poll::Ready(Err(e.into())); diff --git a/src/endpoint/mod.rs b/src/endpoint/mod.rs index 60dca2c..a89ee4e 100644 --- a/src/endpoint/mod.rs +++ b/src/endpoint/mod.rs @@ -19,7 +19,7 @@ use http_body::{Body, Frame, SizeHint}; use http_body_util::{BodyExt, Either, Full}; use pin_project_lite::pin_project; use restate_sdk_shared_core::{ - CoreVM, Error as CoreError, Header, HeaderMap, IdentityVerifier, ResponseHead, VerifyError, VM, + CoreVM, Error as CoreError, Header, HeaderMap, IdentityVerifier, ResponseHead, VM, VerifyError, }; use std::collections::HashMap; use std::convert::Infallible; @@ -27,9 +27,9 @@ use std::future::poll_fn; use std::ops::Deref; use std::pin::Pin; use std::sync::Arc; -use std::task::{ready, Context, Poll}; +use std::task::{Context, Poll, ready}; use tokio::sync::mpsc; -use tracing::{info_span, warn, Instrument}; +use tracing::{Instrument, info_span, warn}; #[allow(clippy::declare_interior_mutable_const)] const X_RESTATE_SERVER: HeaderName = HeaderName::from_static("x-restate-server"); @@ -87,9 +87,13 @@ pub(crate) enum ErrorInner { IdentityVerification(#[from] VerifyError), #[error("Cannot convert header '{0}', reason: {1}")] Header(String, #[source] BoxError), - #[error("Cannot reply to discovery, got accept header '{0}' but currently supported discovery versions are v2 and v3")] + #[error( + "Cannot reply to discovery, got accept header '{0}' but currently supported discovery versions are v2 and v3" + )] BadDiscoveryVersion(String), - #[error("The field '{0}' was set in the service/handler options, but it requires minimum discovery protocol version {1}")] + #[error( + "The field '{0}' was set in the service/handler options, but it requires minimum discovery protocol version {1}" + )] FieldRequiresMinimumVersion(&'static str, u32), #[error("Bad path '{0}', expected either '/discover' or '/invoke/service/handler'")] BadPath(String), @@ -224,7 +228,7 @@ impl Endpoint { let (svc_name, handler_name) = match parts.get(parts.len() - 3..) { None => return error_response(ErrorInner::BadPath(path.to_owned())), Some(last_elements) if last_elements[0] != "invoke" => { - return error_response(ErrorInner::BadPath(path.to_owned())) + return error_response(ErrorInner::BadPath(path.to_owned())); } Some(last_elements) => (last_elements[1].to_owned(), last_elements[2].to_owned()), }; diff --git a/src/filter.rs b/src/filter.rs index c3ae61e..21d9809 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -2,14 +2,14 @@ use std::fmt::Debug; use tracing::{ + Event, Id, Metadata, Subscriber, field::{Field, Visit}, span::{Attributes, Record}, - Event, Id, Metadata, Subscriber, }; use tracing_subscriber::{ + Layer, layer::{Context, Filter}, registry::LookupSpan, - Layer, }; #[derive(Debug)] diff --git a/src/hyper.rs b/src/hyper.rs index f89bce8..c027d33 100644 --- a/src/hyper.rs +++ b/src/hyper.rs @@ -7,7 +7,7 @@ use http::{Request, Response}; use hyper::body::Incoming; use hyper::service::Service; use std::convert::Infallible; -use std::future::{ready, Ready}; +use std::future::{Ready, ready}; /// Wraps [`Endpoint`] to implement hyper [`Service`]. #[derive(Clone)] diff --git a/src/lambda.rs b/src/lambda.rs index 51cc1ea..ca3f0a8 100644 --- a/src/lambda.rs +++ b/src/lambda.rs @@ -75,9 +75,9 @@ use aws_lambda_events::encodings::Base64Data; use bytes::Bytes; use http::{HeaderMap, Method, Request, Uri}; use http_body_util::{BodyExt, Full}; +use lambda_runtime::LambdaEvent; use lambda_runtime::service_fn; use lambda_runtime::tower::ServiceExt; -use lambda_runtime::LambdaEvent; use serde::{Deserialize, Serialize}; use crate::endpoint::{Endpoint, HandleOptions, ProtocolMode}; diff --git a/test-services/Cargo.toml b/test-services/Cargo.toml index 477e793..42a962b 100644 --- a/test-services/Cargo.toml +++ b/test-services/Cargo.toml @@ -1,8 +1,9 @@ [package] name = "test-services" version = "0.1.0" -edition = "2021" +edition = "2024" publish = false +rust-version = "1.85.0" [dependencies] anyhow = "1.0" diff --git a/test-services/Dockerfile b/test-services/Dockerfile index 50e4ff7..faa8bef 100644 --- a/test-services/Dockerfile +++ b/test-services/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.81 +FROM rust:1.85 WORKDIR /app diff --git a/test-services/src/failing.rs b/test-services/src/failing.rs index 197a7af..b7a4939 100644 --- a/test-services/src/failing.rs +++ b/test-services/src/failing.rs @@ -1,7 +1,7 @@ use anyhow::anyhow; use restate_sdk::prelude::*; -use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicI32, Ordering}; use std::time::Duration; #[restate_sdk::object] @@ -17,7 +17,7 @@ pub(crate) trait Failing { async fn terminally_failing_side_effect(error_message: String) -> HandlerResult<()>; #[name = "sideEffectSucceedsAfterGivenAttempts"] async fn side_effect_succeeds_after_given_attempts(minimum_attempts: i32) - -> HandlerResult; + -> HandlerResult; #[name = "sideEffectFailsAfterGivenAttempts"] async fn side_effect_fails_after_given_attempts( retry_policy_max_retry_count: i32, diff --git a/test-services/src/proxy.rs b/test-services/src/proxy.rs index 67f91af..eb30e81 100644 --- a/test-services/src/proxy.rs +++ b/test-services/src/proxy.rs @@ -1,5 +1,5 @@ -use futures::future::BoxFuture; use futures::FutureExt; +use futures::future::BoxFuture; use restate_sdk::context::RequestTarget; use restate_sdk::prelude::*; use schemars::JsonSchema; diff --git a/test-services/src/test_utils_service.rs b/test-services/src/test_utils_service.rs index 325d208..99fbedf 100644 --- a/test-services/src/test_utils_service.rs +++ b/test-services/src/test_utils_service.rs @@ -1,10 +1,10 @@ -use futures::future::BoxFuture; use futures::FutureExt; +use futures::future::BoxFuture; use restate_sdk::prelude::*; use std::collections::HashMap; use std::convert::Infallible; -use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicU8, Ordering}; use std::time::Duration; #[restate_sdk::service] diff --git a/testcontainers/Cargo.toml b/testcontainers/Cargo.toml index f260fa4..a20952c 100644 --- a/testcontainers/Cargo.toml +++ b/testcontainers/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "restate-sdk-testcontainers" version = "0.7.0" -edition = "2021" +edition = "2024" description = "Restate SDK Testcontainers utilities" license = "MIT" repository = "https://github.com/restatedev/sdk-rust" -rust-version = "1.76.0" +rust-version = "1.85.0" [dependencies] diff --git a/testcontainers/src/lib.rs b/testcontainers/src/lib.rs index 30dfeec..49c285c 100644 --- a/testcontainers/src/lib.rs +++ b/testcontainers/src/lib.rs @@ -4,9 +4,9 @@ use restate_sdk::prelude::{Endpoint, HttpServer}; use serde::{Deserialize, Serialize}; use testcontainers::core::wait::HttpWaitStrategy; use testcontainers::{ + ContainerAsync, ContainerRequest, GenericImage, ImageExt, core::{IntoContainerPort, WaitFor}, runners::AsyncRunner, - ContainerAsync, ContainerRequest, GenericImage, ImageExt, }; use tokio::{io::AsyncBufReadExt, net::TcpListener, task}; use tracing::{error, info, warn}; @@ -128,14 +128,20 @@ impl StartedEndpoint { { Ok(res) if res.status().is_success() => break, Ok(res) => { - warn!("Error when waiting for service endpoint server to be healthy, got response {}", res.status()); + warn!( + "Error when waiting for service endpoint server to be healthy, got response {}", + res.status() + ); retries += 1; if retries > 10 { anyhow::bail!("Service endpoint server failed to start") } } Err(err) => { - warn!("Error when waiting for service endpoint server to be healthy, got error {}", err); + warn!( + "Error when waiting for service endpoint server to be healthy, got error {}", + err + ); retries += 1; if retries > 10 { anyhow::bail!("Service endpoint server failed to start")