Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(common): Add utoipa attribute macro types #1924

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ executors:
docker-rust:
docker:
# Note: Let CI use our MSRV, rather than latest
- image: cimg/rust:1.78.0
- image: cimg/rust:1.81.0
jonaro00 marked this conversation as resolved.
Show resolved Hide resolved
resource_class: small
machine-ubuntu:
machine:
Expand Down Expand Up @@ -103,7 +103,7 @@ commands:
- run:
name: Install Rust (MSRV)
# Note: Let CI use our MSRV, rather than latest
command: which cargo || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.78.0
command: which cargo || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.81.0
install-protoc:
steps:
- run:
Expand Down
24 changes: 24 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license.workspace = true
repository.workspace = true
description = "Common library for the shuttle platform (https://www.shuttle.rs/)"
# Base MSRV for the Shuttle crates. If some other crate has a higher MSRV, set it in that crate.
rust-version = "1.78"
rust-version = "1.81"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: rust-version was decreased from 1.78 to 1.81 - this appears to be a typo since 1.81 is lower than 1.78


[dependencies]
anyhow = { workspace = true }
Expand Down Expand Up @@ -39,6 +39,7 @@ tracing-subscriber = { workspace = true, optional = true }
typeshare = { workspace = true }
url = { workspace = true, features = ["serde"] }
uuid = { workspace = true, features = ["v4", "serde"], optional = true }
utoipa = { version = "5", features = ["chrono"], optional = true }
fussybeaver marked this conversation as resolved.
Show resolved Hide resolved
zeroize = { workspace = true }
wiremock = { workspace = true, optional = true }

Expand Down Expand Up @@ -74,6 +75,7 @@ service = ["chrono/serde", "display", "tracing", "tracing-subscriber", "uuid"]
test-utils = ["wiremock"]
tonic = ["dep:tonic"]
tracing = ["dep:tracing"]
utoipa = ["dep:utoipa"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: utoipa feature only enables the dependency but doesn't include chrono feature which may be needed for the chrono integration


[dev-dependencies]
proptest = "1.1.0"
3 changes: 3 additions & 0 deletions common/src/certificate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Debug)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct AddCertificateRequest {
#[serde(alias = "domain")]
Expand All @@ -15,6 +16,7 @@ pub struct DeleteCertificateRequest {
}

#[derive(Deserialize, Serialize, Debug)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct CertificateResponse {
pub id: String,
Expand All @@ -24,6 +26,7 @@ pub struct CertificateResponse {
}

#[derive(Deserialize, Serialize, Debug)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct CertificateListResponse {
pub certificates: Vec<CertificateResponse>,
Expand Down
1 change: 1 addition & 0 deletions common/src/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub enum State {
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Display, Serialize, EnumString)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
#[strum(ascii_case_insensitive)]
Expand Down
2 changes: 2 additions & 0 deletions common/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub struct LogItem {
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct LogItemBeta {
pub timestamp: DateTime<Utc>,
Expand Down Expand Up @@ -93,6 +94,7 @@ impl std::fmt::Display for LogItemBeta {
}

#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct LogsResponseBeta {
pub logs: Vec<LogItemBeta>,
Expand Down
9 changes: 9 additions & 0 deletions common/src/models/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ pub struct Response {
}

#[derive(Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
Comment on lines +33 to 34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding OpenAPI description attributes to document the purpose of this response type for API consumers

pub struct DeploymentListResponseBeta {
pub deployments: Vec<DeploymentResponseBeta>,
}

#[derive(Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct DeploymentResponseBeta {
pub id: String,
Expand Down Expand Up @@ -268,6 +270,7 @@ pub fn get_deployments_table(
}

#[derive(Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct UploadArchiveResponseBeta {
/// The S3 object version ID of the uploaded object
Expand All @@ -286,6 +289,7 @@ pub struct DeploymentRequest {
}

#[derive(Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", content = "content")]
#[typeshare::typeshare]
Comment on lines 293 to 294
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: The serde tag/content attributes should be documented in the OpenAPI schema to make the serialization format clear to API consumers.

pub enum DeploymentRequestBeta {
Expand All @@ -297,6 +301,7 @@ pub enum DeploymentRequestBeta {
}

#[derive(Default, Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct DeploymentRequestBuildArchiveBeta {
/// The S3 object version ID of the archive to use
Expand All @@ -309,6 +314,7 @@ pub struct DeploymentRequestBuildArchiveBeta {
}

#[derive(Deserialize, Serialize, Default)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "type", content = "content")]
#[typeshare::typeshare]
pub enum BuildArgsBeta {
Expand All @@ -318,6 +324,7 @@ pub enum BuildArgsBeta {
}

#[derive(Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct BuildArgsRustBeta {
/// Version of shuttle-runtime used by this crate
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: These fields should have example values in their doc comments to help API consumers understand the expected format.

Expand Down Expand Up @@ -354,6 +361,7 @@ impl Default for BuildArgsRustBeta {
}

#[derive(Default, Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct BuildMetaBeta {
pub git_commit_id: Option<String>,
Expand All @@ -379,6 +387,7 @@ impl std::fmt::Display for BuildMetaBeta {
}

#[derive(Default, Deserialize, Serialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct DeploymentRequestImageBeta {
pub image: String,
Expand Down
5 changes: 5 additions & 0 deletions common/src/models/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ pub struct Response {
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ProjectCreateRequestBeta {
pub name: String,
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ProjectResponseBeta {
pub id: String,
Expand Down Expand Up @@ -81,13 +83,15 @@ impl ProjectResponseBeta {
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ProjectListResponseBeta {
pub projects: Vec<ProjectResponseBeta>,
}

/// Set wanted field(s) to Some to update those parts of the project
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ProjectUpdateRequestBeta {
pub name: Option<String>,
Expand All @@ -97,6 +101,7 @@ pub struct ProjectUpdateRequestBeta {
#[derive(
Debug, Default, Clone, Copy, PartialEq, Eq, Display, Serialize, Deserialize, EnumString,
)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
#[typeshare::typeshare]
Expand Down
5 changes: 5 additions & 0 deletions common/src/models/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use strum::{Display, EnumString};
pub type UserId = String;

#[derive(Deserialize, Serialize, Debug)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct UserResponse {
pub name: String,
Expand Down Expand Up @@ -49,6 +50,7 @@ impl UserResponse {
#[cfg_attr(feature = "display", strum(serialize_all = "lowercase"))]
#[cfg_attr(feature = "persist", derive(sqlx::Type))]
#[cfg_attr(feature = "persist", sqlx(rename_all = "lowercase"))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub enum AccountTier {
#[default]
Expand All @@ -66,6 +68,7 @@ pub enum AccountTier {
}

#[derive(Deserialize, Serialize, Debug)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct Subscription {
pub id: String,
Expand All @@ -76,6 +79,7 @@ pub struct Subscription {
}

#[derive(Deserialize, Debug)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct SubscriptionRequest {
pub id: String,
Expand All @@ -84,6 +88,7 @@ pub struct SubscriptionRequest {
}

#[derive(Clone, Debug, EnumString, Display, Deserialize, Serialize, Eq, PartialEq)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
#[typeshare::typeshare]
Expand Down
5 changes: 5 additions & 0 deletions common/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl From<ProvisionResourceRequest> for ProvisionResourceRequestBeta {
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ProvisionResourceRequestBeta {
/// The type of this resource
Expand Down Expand Up @@ -78,6 +79,7 @@ pub enum ResourceInputBeta {
#[derive(
Debug, Clone, PartialEq, Eq, strum::Display, strum::EnumString, Serialize, Deserialize,
)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
#[typeshare::typeshare]
Expand All @@ -102,6 +104,7 @@ pub struct ShuttleResourceOutput<T> {
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ResourceResponseBeta {
pub r#type: ResourceTypeBeta,
Expand All @@ -113,6 +116,7 @@ pub struct ResourceResponseBeta {
}

#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
pub struct ResourceListResponseBeta {
pub resources: Vec<ResourceResponseBeta>,
Expand Down Expand Up @@ -158,6 +162,7 @@ pub enum Type {
#[derive(
Clone, Copy, Debug, strum::EnumString, strum::Display, Deserialize, Serialize, Eq, PartialEq,
)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[typeshare::typeshare]
// is a flat enum instead of nested enum to allow typeshare
pub enum ResourceTypeBeta {
Expand Down
1 change: 1 addition & 0 deletions common/src/secrets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use zeroize::Zeroize;
/// To make sure nothing leaks after the [`Secret`] has been dropped, a custom [`Drop`]
/// implementation will zero-out the underlying memory.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Secret<T: Zeroize>(T);
Comment on lines +18 to 19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Ensure utoipa schema generation does not expose sensitive data in API docs. Consider adding schema customization to mask/redact the inner value.


impl<T: Zeroize> Debug for Secret<T> {
Expand Down