Skip to content
Draft
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
86 changes: 86 additions & 0 deletions .github/workflows/samples-rust-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Samples Rust Servers

on:
push:
paths:
- "samples/server/petstore/rust-server/**"
- "samples/server/petstore/rust-axum/**"
pull_request:
paths:
- "samples/server/petstore/rust-server/**"
- "samples/server/petstore/rust-axum/**"

jobs:
build:
name: Build Rust
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# these folders contain sub-projects of rust clients, servers
- samples/server/petstore/rust-server/
- samples/server/petstore/rust-server-deprecated/
- samples/server/petstore/rust-axum/
steps:
- uses: actions/checkout@v5
- uses: actions-rs/toolchain@v1
with:
toolchain: stable

- name: Rust cache
uses: Swatinem/rust-cache@v2
with:
cache-targets: false # Don't cache workspace target directories as they don't exist
cache-directories:
${{ matrix.sample }}/target
workspaces: |
${{ matrix.sample }}/output/*

- name: Build
working-directory: ${{ matrix.sample }}
run: |
set -e
cargo build --all-targets --all-features
cargo build --all-targets --no-default-features
- name: Tests
working-directory: ${{ matrix.sample }}
run: |
set -e

# Iterate through each package and test various features
for package in $(find output -maxdepth 1 -mindepth 1 -type d)
do
pushd $package
# Not all versions have a server example
if test -f examples/server/main.rs; then
cargo build --example ${package##*/}-server --features="server"
fi
# Not all versions have a client example
if test -f examples/client/main.rs; then
cargo build --example ${package##*/}-client --features="client"
fi
# Test the CLI works if present
if test -f bin/cli.rs; then
cargo build --bin ${package##*/} --features cli
../../target/debug/${package##*/} --help
fi
# Test the validate feature if it exists
if cargo read-manifest | grep -q '"validate"'; then
cargo build --features validate --all-targets
fi
# Test TLS features if they exist
if cargo read-manifest | grep -q '"client-tls"'; then
# Client without TLS (HTTP-only)
cargo build --no-default-features --features=client --lib
# Client with TLS (using native-tls)
cargo build --no-default-features --features=client,client-tls --lib
# Server without TLS
cargo build --no-default-features --features=server --lib
fi
cargo fmt
cargo test
cargo clippy
cargo doc
popd
done
161 changes: 106 additions & 55 deletions modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -28,128 +28,179 @@ repository = "{{.}}"
documentation = "{{.}}"
{{/documentationUrl}}
{{#homePageUrl}}
homepage = "{{.}}
homepage = "{{.}}"
{{/homePageUrl}}

[features]
default = ["client", "server"]
default = ["client", "server", "client-tls"]
client = [
{{#apiUsesMultipart}}
"mime_0_2",
{{/apiUsesMultipart}}
{{#apiUsesMultipartFormData}}
"multipart", "multipart/client", "swagger/multipart_form",
{{/apiUsesMultipartFormData}}
{{#apiUsesMultipartRelated}}
"hyper_0_10", "mime_multipart",
"mime_multipart", "swagger/multipart_related",
{{/apiUsesMultipartRelated}}
{{#usesUrlEncodedForm}}
"serde_urlencoded",
{{/usesUrlEncodedForm}}
{{#hasCallbacks}}
"serde_ignored", "regex", "percent-encoding", "lazy_static",
"serde_ignored", "percent-encoding", {{^apiUsesByteArray}}"lazy_static", "regex",{{/apiUsesByteArray}}
{{/hasCallbacks}}
{{! Anything added to the list below, should probably be added to the callbacks list below }}
"hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url"
"hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url"
]
# TLS support - automatically selects backend based on target OS:
# - macOS/Windows/iOS: native-tls via hyper-tls
# - Other platforms: OpenSSL via hyper-openssl
# Dependencies are in target-specific sections below
client-tls = [
"client",
"dep:native-tls",
"dep:hyper-tls",
"dep:openssl",
"dep:hyper-openssl",
"swagger/tls"
]
server = [
{{#apiUsesMultipart}}
"mime_0_2",
{{/apiUsesMultipart}}
{{#apiUsesMultipartFormData}}
"multipart", "multipart/server", "swagger/multipart_form",
{{/apiUsesMultipartFormData}}
{{#apiUsesMultipartRelated}}
"hyper_0_10", "mime_multipart",
"mime_multipart", "swagger/multipart_related",
{{/apiUsesMultipartRelated}}
{{#hasCallbacks}}
"native-tls", "hyper-openssl", "hyper-tls", "openssl",
"hyper-util/http1", "hyper-util/http2",
{{/hasCallbacks}}
{{! Anything added to the list below, should probably be added to the callbacks list above }}
"serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static"
"serde_ignored", "hyper", "percent-encoding", "url",
{{^apiUsesByteArray}}"lazy_static", "regex"{{/apiUsesByteArray}}
]
cli = [
{{#apiHasDeleteMethods}}
"dialoguer",
{{/apiHasDeleteMethods}}
"anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio"
]
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]

[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies]
native-tls = { version = "0.2", optional = true }
hyper-tls = { version = "0.5", optional = true }

[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies]
hyper-openssl = { version = "0.9", optional = true }
openssl = {version = "0.10", optional = true }
mock = ["mockall"]
validate = [{{^apiUsesByteArray}}"regex",{{/apiUsesByteArray}} "serde_valid", "swagger/serdevalid"]

[dependencies]
# Common
async-trait = "0.1.24"
async-trait = "0.1.89"
chrono = { version = "0.4", features = ["serde"] }
futures = "0.3"
swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] }
log = "0.4.0"
swagger = { version = "7.0.0", features = ["serdejson", "server", "client"] }
headers = "0.4.1"
log = "0.4.29"

mime = "0.3"
mockall = { version = "0.14", optional = true }
{{#apiUsesByteArray}}
lazy_static = "1.5"
regex = "1.12"
{{/apiUsesByteArray}}


serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
validator = { version = "0.16", features = ["derive"] }
{{#apiUsesIntegerEnums}}
serde_repr = "0.1"
{{/apiUsesIntegerEnums}}
serde_valid = { version = "2.0", optional = true }

validator = { version = "0.20", features = ["derive"] }

# Crates included if required by the API definition
{{#usesXml}}
# TODO: this should be updated to point at the official crate once
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"}
serde-xml-rs = "0.8"
{{/usesXml}}
{{#apiUsesMultipart}}
mime_0_2 = { package = "mime", version = "0.2.6", optional = true }
{{/apiUsesMultipart}}
{{#apiUsesMultipartFormData}}
multipart = { version = "0.16", default-features = false, optional = true }
multipart = { version = "0.18", default-features = false, optional = true }
{{/apiUsesMultipartFormData}}
{{#apiUsesUuid}}
uuid = {version = "1.3.1", features = ["serde", "v4"]}
uuid = { version = "1.23.0", features = ["serde", "v4"]}
{{/apiUsesUuid}}

# Common between server and client features
hyper = {version = "0.14", features = ["full"], optional = true}
bytes = "1.11"
http-body-util = "0.1.3"
hyper = { version = "1.9.0", features = ["full"], optional = true }
hyper-util = { version = "0.1.20", features = ["service"] }
{{#apiUsesMultipartRelated}}
mime_multipart = {version = "0.5", optional = true}
hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true}
mime_multipart = { version = "0.10", optional = true, package = "mime-multipart-hyper1" }
{{/apiUsesMultipartRelated}}
serde_ignored = {version = "0.1.1", optional = true}
url = {version = "2.1", optional = true}
serde_ignored = { version = "0.1.14", optional = true }
url = { version = "2.5", optional = true }

# Client-specific
{{#usesUrlEncodedForm}}
serde_urlencoded = {version = "0.6.1", optional = true}
serde_urlencoded = { version = "0.7.1", optional = true }
{{/usesUrlEncodedForm}}
tower-service = "0.3.3"

# Server, and client callback-specific
lazy_static = { version = "1.4", optional = true }
percent-encoding = {version = "2.1.0", optional = true}
regex = {version = "1.3", optional = true}
{{^apiUsesByteArray}}
lazy_static = { version = "1.5", optional = true }
regex = { version = "1.12", optional = true }
{{/apiUsesByteArray}}
percent-encoding = { version = "2.3.2", optional = true }

# CLI-specific
anyhow = { version = "1", optional = true }
clap = { version = "4.6.0", features = ["env"], optional = true }
clap-verbosity-flag = { version = "3.0", optional = true }
simple_logger = { version = "5.2.0", features = ["stderr"], optional = true }
tokio = { version = "1.50.0", features = ["rt-multi-thread", "macros"], optional = true }
{{#apiHasDeleteMethods}}
dialoguer = { version = "0.12", optional = true }
{{/apiHasDeleteMethods}}

# Conversion
frunk = { version = "0.3.0", optional = true }
frunk_derives = { version = "0.3.0", optional = true }
frunk_core = { version = "0.3.0", optional = true }
frunk-enum-derive = { version = "0.2.0", optional = true }
frunk-enum-core = { version = "0.2.0", optional = true }
frunk = { version = "0.4.4", optional = true }
frunk_derives = { version = "0.4.4", optional = true }
frunk_core = { version = "0.4.4", optional = true }
frunk-enum-derive = { version = "0.3.0", optional = true }
frunk-enum-core = { version = "0.3.0", optional = true }

# Bearer authentication
jsonwebtoken = { version = "9.3.0", optional = false }
# TLS dependencies - platform-specific backends
# On macOS/Windows/iOS, use native-tls via hyper-tls
[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies]
native-tls = { version = "0.2", optional = true }
hyper-tls = { version = "0.6", optional = true }

# On other platforms (Linux, etc.), use OpenSSL via hyper-openssl
[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies]
openssl = { version = "0.10", optional = true }
hyper-openssl = { version = "0.10", optional = true }

[dev-dependencies]
clap = "2.25"
env_logger = "0.7"
tokio = { version = "1.14", features = ["full"] }
always_send = "0.1.1"
clap = "4.6.0"
env_logger = "0.11"
tokio = { version = "1.50.0", features = ["full"] }
native-tls = "0.2"
pin-project = "1.1.11"

# Bearer authentication, used in examples
jsonwebtoken = {version = "10.3.0", features = ["rust_crypto"]}

[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies]
tokio-openssl = "0.6"
openssl = "0.10"
tokio-openssl = "0.6"

[[example]]
name = "client"
name = "{{{packageName}}}-client"
path = "examples/client/main.rs"
required-features = ["client"]

[[example]]
name = "server"
name = "{{{packageName}}}-server"
path = "examples/server/main.rs"
required-features = ["server"]

[[bin]]
name = "{{{packageName}}}"
path = "bin/cli.rs"
required-features = ["client", "cli"]
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The Rust Server Generator templates use Mustache Partials.
The following tree shows which templates include which:

- `api_doc.mustache`
- `bin-cli.mustache`
- `cargo-config`
- `Cargo.mustache`
- `context.mustache`
Expand Down
Loading
Loading