diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4edb7a5..3bb2e55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,3 +46,15 @@ jobs: - run: cargo doc --no-deps --all-features env: RUSTDOCFLAGS: -D warnings + + # Regression guard: generate clients for our reference specs (Anthropic + + # OpenAI) and `cargo check` the result. Catches breakage where a generator + # change still passes unit tests but emits invalid Rust against real-world + # OAS documents. See scripts/spec-compile.sh. + spec-compile: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - run: scripts/spec-compile.sh diff --git a/.gitignore b/.gitignore index 6ebcb4b..ac7661b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ /target +**/target/ +# Build outputs from spec-compile.sh and ad-hoc generator runs. +/tmp/spec-compile/ +/tmp/gen-anthropic/ +/tmp/gen-openai/ *.swp *.swo *~ diff --git a/scripts/spec-compile.sh b/scripts/spec-compile.sh new file mode 100755 index 0000000..bb8a813 --- /dev/null +++ b/scripts/spec-compile.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +# Smoke-test that generated clients for our reference specs compile cleanly. +# Each spec listed below produces a separate scratch crate; we run the +# `openapi-to-rust` generator into it and then `cargo check`. Any +# regression here means a real-world spec stops compiling. +# +# Usage: +# scripts/spec-compile.sh # run all specs in SPECS +# scripts/spec-compile.sh anthropic openai # run a subset +# +# Env: +# SPEC_COMPILE_KEEP=1 keep the scratch directory under tmp/spec-compile/ +# SPEC_COMPILE_OFFLINE=1 pass --offline to cargo invocations +set -euo pipefail +cd "$(dirname "$0")/.." + +# (spec_name, spec_path, base_url, auth_type, auth_header) +SPECS=( + "anthropic|specs/anthropic.yaml|https://api.anthropic.com|ApiKey|x-api-key" + "openai|specs/openai.yaml|https://api.openai.com/v1|Bearer|Authorization" +) + +# If args are given, treat them as a whitelist of spec names. +WANT=("$@") + +OFFLINE="" +if [ "${SPEC_COMPILE_OFFLINE:-}" = "1" ]; then + OFFLINE="--offline" +fi + +echo "[spec-compile] building openapi-to-rust binary..." +cargo build --bin openapi-to-rust $OFFLINE >/dev/null + +GEN_BIN="$(pwd)/target/debug/openapi-to-rust" + +ROOT="$(pwd)/tmp/spec-compile" +rm -rf "$ROOT" +mkdir -p "$ROOT" + +failed=() +for entry in "${SPECS[@]}"; do + IFS='|' read -r name spec_path base_url auth_type auth_header <<<"$entry" + if [ ${#WANT[@]} -gt 0 ]; then + skip=1 + for w in "${WANT[@]}"; do [ "$w" = "$name" ] && skip=0; done + [ $skip -eq 1 ] && continue + fi + + echo + echo "==> $name (spec: $spec_path)" + dir="$ROOT/$name" + mkdir -p "$dir/src/generated" + + cat >"$dir/Cargo.toml" <"$dir/src/lib.rs" <"$dir/openapi-to-rust.toml" </dev/null + if ! cargo check $OFFLINE 2>&1 | tail -200; then + echo "[spec-compile] $name FAILED to compile" >&2 + exit 1 + fi + ) || failed+=("$name") +done + +if [ "${SPEC_COMPILE_KEEP:-}" != "1" ]; then + rm -rf "$ROOT" +fi + +if [ ${#failed[@]} -gt 0 ]; then + echo + echo "[spec-compile] FAILED: ${failed[*]}" >&2 + exit 1 +fi + +echo +echo "[spec-compile] ✅ all specs compiled cleanly" diff --git a/src/analysis.rs b/src/analysis.rs index e3b3789..2781191 100644 --- a/src/analysis.rs +++ b/src/analysis.rs @@ -3860,6 +3860,30 @@ impl SchemaAnalyzer { /// when the parameter's inline schema is a string with `enum` or `const` /// (e.g. `GetItemTheConstant`). The client generator emits the enum /// alongside the operation methods. See issue #10 follow-up. + /// Look up `#/components/schemas/{name}` in the raw OpenAPI document and + /// decide whether it's a string with enum values. Used by analyze_parameter + /// (T10) so that only string-enum refs flow through to the codegen-typed + /// parameter path; struct/object refs stay as `String` until we have + /// proper deepObject / form-style query serialization (T14). + fn referenced_schema_is_string_enum(&self, name: &str) -> bool { + let Some(schema_value) = self + .openapi_spec + .get("components") + .and_then(|c| c.get("schemas")) + .and_then(|s| s.get(name)) + else { + return false; + }; + let is_string_type = schema_value + .get("type") + .and_then(|v| v.as_str()) + .map(|s| s == "string") + .unwrap_or(false); + let has_enum_or_const = + schema_value.get("enum").is_some() || schema_value.get("const").is_some(); + is_string_type && has_enum_or_const + } + fn analyze_parameter( &self, param: &crate::openapi::Parameter, @@ -3877,7 +3901,17 @@ impl SchemaAnalyzer { if let Some(schema) = ¶m.schema { if let Some(ref_str) = schema.reference() { - schema_ref = self.extract_schema_name(ref_str).map(|s| s.to_string()); + // T10: keep the resolved type when the target is a string-enum + // (then `Display`/`as_str` are emitted, see generate_string_enum). + // For struct/object refs we fall back to `String` here — those + // need deepObject / form / serde_urlencoded handling that's + // not yet generated; emitting the typed name would produce + // `(struct).to_string()` and not compile. + if let Some(name) = self.extract_schema_name(ref_str) { + if self.referenced_schema_is_string_enum(name) { + schema_ref = Some(name.to_string()); + } + } } else if let Some(schema_type) = schema.schema_type() { rust_type = match schema_type { crate::openapi::SchemaType::Boolean => "bool", diff --git a/src/client_generator.rs b/src/client_generator.rs index 2728ade..4b0d616 100644 --- a/src/client_generator.rs +++ b/src/client_generator.rs @@ -611,8 +611,8 @@ impl CodeGenerator { ) -> Result<#response_type, ApiOpError<#op_error_type>> { #url_construction - let mut req = #http_method_call - #request_body; + let mut req = #http_method_call; + #request_body #query_params #header_params @@ -706,7 +706,7 @@ impl CodeGenerator { let param_ident = Self::to_field_ident(¶m_name_snake); let header_name = ¶m.name; if param.required { - if param.rust_type == "String" { + if Self::param_uses_as_ref_str(param) { emit.push(quote! { req = req.header(#header_name, #param_ident.as_ref()); }); @@ -715,7 +715,7 @@ impl CodeGenerator { req = req.header(#header_name, #param_ident.to_string()); }); } - } else if param.rust_type == "String" { + } else if Self::param_uses_as_ref_str(param) { emit.push(quote! { if let Some(v) = #param_ident { req = req.header(#header_name, v.as_ref()); @@ -758,7 +758,7 @@ impl CodeGenerator { if param.required { // Required parameters: always add - if param.rust_type == "String" { + if Self::param_uses_as_ref_str(param) { param_building.push(quote! { query_params.push((#param_key, #param_name.as_ref().to_string())); }); @@ -769,7 +769,7 @@ impl CodeGenerator { } } else { // Optional parameters: add only if Some - if param.rust_type == "String" { + if Self::param_uses_as_ref_str(param) { param_building.push(quote! { if let Some(v) = #param_name { query_params.push((#param_key, v.as_ref().to_string())); @@ -993,43 +993,72 @@ impl CodeGenerator { } } + /// True when the parameter's compile-time type is `impl AsRef` and + /// we should call `.as_ref()` on it before stringifying. False for any + /// $ref-resolved type (T10) or non-String primitive — those just call + /// `.to_string()`. + fn param_uses_as_ref_str(param: &crate::analysis::ParameterInfo) -> bool { + param.schema_ref.is_none() && param.rust_type == "String" + } + /// Generate request body serialization based on content type + /// Emit statements that mutate `req` to apply the request body. Returns + /// `quote!{}` if the operation has no body. Optional bodies (T11) gate the + /// application on `Some(_)`; required bodies apply unconditionally. fn generate_request_body(&self, op: &OperationInfo) -> TokenStream { - if let Some(ref rb) = op.request_body { - use crate::analysis::RequestBodyContent; - match rb { - RequestBodyContent::Json { .. } => { - quote! { + let Some(rb) = op.request_body.as_ref() else { + return quote! {}; + }; + use crate::analysis::RequestBodyContent; + let required = op.request_body_required; + let (ident, apply): (TokenStream, TokenStream) = match rb { + RequestBodyContent::Json { .. } => ( + quote! { request }, + quote! { + req = req .body(serde_json::to_vec(&request).map_err(HttpError::serialization_error)?) - .header("content-type", "application/json") - } - } - RequestBodyContent::FormUrlEncoded { .. } => { - quote! { + .header("content-type", "application/json"); + }, + ), + RequestBodyContent::FormUrlEncoded { .. } => ( + quote! { request }, + quote! { + req = req .body(serde_urlencoded::to_string(&request).map_err(HttpError::serialization_error)?) - .header("content-type", "application/x-www-form-urlencoded") - } - } - RequestBodyContent::Multipart => { - quote! { - .multipart(form) - } - } - RequestBodyContent::OctetStream => { - quote! { + .header("content-type", "application/x-www-form-urlencoded"); + }, + ), + RequestBodyContent::Multipart => ( + quote! { form }, + quote! { + req = req.multipart(form); + }, + ), + RequestBodyContent::OctetStream => ( + quote! { body }, + quote! { + req = req .body(body) - .header("content-type", "application/octet-stream") - } - } - RequestBodyContent::TextPlain => { - quote! { + .header("content-type", "application/octet-stream"); + }, + ), + RequestBodyContent::TextPlain => ( + quote! { body }, + quote! { + req = req .body(body) - .header("content-type", "text/plain") - } + .header("content-type", "text/plain"); + }, + ), + }; + if required { + apply + } else { + quote! { + if let Some(#ident) = #ident { + #apply } } - } else { - quote! {} } } @@ -1258,7 +1287,7 @@ impl CodeGenerator { let param_name_snake = self.sanitize_param_name(¶m.name); let param_ident = Self::to_field_ident(¶m_name_snake); - if param.rust_type == "String" { + if Self::param_uses_as_ref_str(param) { format_args.push(quote! { __pct_encode_path_segment(#param_ident.as_ref()) }); diff --git a/src/generator.rs b/src/generator.rs index b1f362e..44bef16 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -859,30 +859,43 @@ impl CodeGenerator { .and_then(|v| v.as_str()) .map(|s| s.to_string()); - let variants = values.iter().enumerate().map(|(i, value)| { - // Convert string value to valid Rust enum variant (PascalCase) - let variant_name = self.to_rust_enum_variant(value); - let variant_ident = format_ident!("{}", variant_name); - - // Check if this variant should be the default - let is_default = if let Some(ref default) = default_value { - value == default - } else { - i == 0 // Fall back to first variant if no default specified - }; + let variant_pairs: Vec<(syn::Ident, &String, bool)> = values + .iter() + .enumerate() + .map(|(i, value)| { + let variant_name = self.to_rust_enum_variant(value); + let variant_ident = format_ident!("{}", variant_name); + let is_default = if let Some(ref default) = default_value { + value == default + } else { + i == 0 + }; + (variant_ident, value, is_default) + }) + .collect(); - if is_default { - quote! { - #[default] - #[serde(rename = #value)] - #variant_ident, - } - } else { - quote! { - #[serde(rename = #value)] - #variant_ident, + let variants = variant_pairs + .iter() + .map(|(variant_ident, value, is_default)| { + if *is_default { + quote! { + #[default] + #[serde(rename = #value)] + #variant_ident, + } + } else { + quote! { + #[serde(rename = #value)] + #variant_ident, + } } - } + }); + + // T13/T10: emit `as_str` and `Display` so the enum can be embedded in + // query strings, headers, and path segments without requiring callers + // to reach for `serde_json` round-trips. + let as_str_arms = variant_pairs.iter().map(|(variant_ident, value, _)| { + quote! { Self::#variant_ident => #value, } }); let doc_comment = if let Some(desc) = &schema.description { @@ -909,6 +922,26 @@ impl CodeGenerator { pub enum #enum_name { #(#variants)* } + + impl #enum_name { + pub fn as_str(&self) -> &'static str { + match self { + #(#as_str_arms)* + } + } + } + + impl ::std::fmt::Display for #enum_name { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } + } + + impl AsRef for #enum_name { + fn as_ref(&self) -> &str { + self.as_str() + } + } }) } diff --git a/src/snapshots/openapi_to_rust__test_helpers__allof_wrapper_in_oneof.snap b/src/snapshots/openapi_to_rust__test_helpers__allof_wrapper_in_oneof.snap index 548c2b9..2976f54 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__allof_wrapper_in_oneof.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__allof_wrapper_in_oneof.snap @@ -31,6 +31,23 @@ pub enum TextBlockType { #[serde(rename = "text")] Text, } +impl TextBlockType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Text => "text", + } + } +} +impl ::std::fmt::Display for TextBlockType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TextBlockType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ImageBlock { pub url: String, @@ -41,6 +58,23 @@ pub enum ImageBlockType { #[serde(rename = "image")] Image, } +impl ImageBlockType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Image => "image", + } + } +} +impl ::std::fmt::Display for ImageBlockType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ImageBlockType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct DocumentBlock { pub content: String, @@ -51,3 +85,20 @@ pub enum DocumentBlockType { #[serde(rename = "document")] Document, } +impl DocumentBlockType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Document => "document", + } + } +} +impl ::std::fmt::Display for DocumentBlockType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for DocumentBlockType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__array_union_items.snap b/src/snapshots/openapi_to_rust__test_helpers__array_union_items.snap index 0e9a79d..2c34df3 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__array_union_items.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__array_union_items.snap @@ -33,6 +33,23 @@ pub enum TextToolType { #[serde(rename = "text")] Text, } +impl TextToolType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Text => "text", + } + } +} +impl ::std::fmt::Display for TextToolType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TextToolType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct CodeTool { pub language: String, @@ -43,3 +60,20 @@ pub enum CodeToolType { #[serde(rename = "code")] Code, } +impl CodeToolType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Code => "code", + } + } +} +impl ::std::fmt::Display for CodeToolType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for CodeToolType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__complex_nested.snap b/src/snapshots/openapi_to_rust__test_helpers__complex_nested.snap index d5a20d4..10c6541 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__complex_nested.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__complex_nested.snap @@ -35,4 +35,23 @@ pub enum MessageBatchStatus { #[serde(rename = "failed")] Failed, } +impl MessageBatchStatus { + pub fn as_str(&self) -> &'static str { + match self { + Self::Pending => "pending", + Self::Completed => "completed", + Self::Failed => "failed", + } + } +} +impl ::std::fmt::Display for MessageBatchStatus { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for MessageBatchStatus { + fn as_ref(&self) -> &str { + self.as_str() + } +} pub type BetaListResponseMessageBatchLastId = String; diff --git a/src/snapshots/openapi_to_rust__test_helpers__const_and_enum.snap b/src/snapshots/openapi_to_rust__test_helpers__const_and_enum.snap index f493e0b..e028391 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__const_and_enum.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__const_and_enum.snap @@ -24,3 +24,20 @@ pub enum AssistantMessageRole { #[serde(rename = "assistant")] Assistant, } +impl AssistantMessageRole { + pub fn as_str(&self) -> &'static str { + match self { + Self::Assistant => "assistant", + } + } +} +impl ::std::fmt::Display for AssistantMessageRole { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for AssistantMessageRole { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__const_enum_property.snap b/src/snapshots/openapi_to_rust__test_helpers__const_enum_property.snap index 289dc5c..00c0a67 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__const_enum_property.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__const_enum_property.snap @@ -34,6 +34,23 @@ pub enum MessageRole { #[serde(rename = "assistant")] Assistant, } +impl MessageRole { + pub fn as_str(&self) -> &'static str { + match self { + Self::Assistant => "assistant", + } + } +} +impl ::std::fmt::Display for MessageRole { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for MessageRole { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct MessageContentInlineVariant2Item {} ///The content of the message. diff --git a/src/snapshots/openapi_to_rust__test_helpers__const_enum_test.snap b/src/snapshots/openapi_to_rust__test_helpers__const_enum_test.snap index b440336..be264c7 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__const_enum_test.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__const_enum_test.snap @@ -29,3 +29,20 @@ pub enum MessageRole { #[serde(rename = "assistant")] Assistant, } +impl MessageRole { + pub fn as_str(&self) -> &'static str { + match self { + Self::Assistant => "assistant", + } + } +} +impl ::std::fmt::Display for MessageRole { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for MessageRole { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__const_only_property.snap b/src/snapshots/openapi_to_rust__test_helpers__const_only_property.snap index c2e159e..182ac7c 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__const_only_property.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__const_only_property.snap @@ -22,3 +22,20 @@ pub enum ConstModifierSomeConstant { #[serde(rename = "TheOnlyValidValue")] TheOnlyValidValue, } +impl ConstModifierSomeConstant { + pub fn as_str(&self) -> &'static str { + match self { + Self::TheOnlyValidValue => "TheOnlyValidValue", + } + } +} +impl ::std::fmt::Display for ConstModifierSomeConstant { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ConstModifierSomeConstant { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__const_only_required.snap b/src/snapshots/openapi_to_rust__test_helpers__const_only_required.snap index 510bea1..9110142 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__const_only_required.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__const_only_required.snap @@ -21,3 +21,20 @@ pub enum RequiredConstKind { #[serde(rename = "fixed")] Fixed, } +impl RequiredConstKind { + pub fn as_str(&self) -> &'static str { + match self { + Self::Fixed => "fixed", + } + } +} +impl ::std::fmt::Display for RequiredConstKind { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for RequiredConstKind { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__content_delta_test.snap b/src/snapshots/openapi_to_rust__test_helpers__content_delta_test.snap index 6cfe4b8..4ec8730 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__content_delta_test.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__content_delta_test.snap @@ -32,6 +32,23 @@ pub enum CreateChatCompletionStreamResponseObject { #[serde(rename = "chat.completion.chunk")] ChatCompletionChunk, } +impl CreateChatCompletionStreamResponseObject { + pub fn as_str(&self) -> &'static str { + match self { + Self::ChatCompletionChunk => "chat.completion.chunk", + } + } +} +impl ::std::fmt::Display for CreateChatCompletionStreamResponseObject { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for CreateChatCompletionStreamResponseObject { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct CreateChatCompletionStreamResponseChoicesItem { pub delta: ChatCompletionStreamResponseDelta, @@ -67,6 +84,27 @@ pub enum CreateChatCompletionStreamResponseFinishReason { #[serde(rename = "function_call")] FunctionCall, } +impl CreateChatCompletionStreamResponseFinishReason { + pub fn as_str(&self) -> &'static str { + match self { + Self::Stop => "stop", + Self::Length => "length", + Self::ToolCalls => "tool_calls", + Self::ContentFilter => "content_filter", + Self::FunctionCall => "function_call", + } + } +} +impl ::std::fmt::Display for CreateChatCompletionStreamResponseFinishReason { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for CreateChatCompletionStreamResponseFinishReason { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ChatCompletionTokenLogprob { #[serde(skip_serializing_if = "Option::is_none")] @@ -95,3 +133,24 @@ pub enum ChatCompletionStreamResponseDeltaRole { #[serde(rename = "tool")] Tool, } +impl ChatCompletionStreamResponseDeltaRole { + pub fn as_str(&self) -> &'static str { + match self { + Self::Developer => "developer", + Self::System => "system", + Self::User => "user", + Self::Assistant => "assistant", + Self::Tool => "tool", + } + } +} +impl ::std::fmt::Display for ChatCompletionStreamResponseDeltaRole { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ChatCompletionStreamResponseDeltaRole { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__create_response_input_typing.snap b/src/snapshots/openapi_to_rust__test_helpers__create_response_input_typing.snap index b131077..51d4d99 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__create_response_input_typing.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__create_response_input_typing.snap @@ -37,6 +37,24 @@ pub enum InputItemType { #[serde(rename = "image")] Image, } +impl InputItemType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Text => "text", + Self::Image => "image", + } + } +} +impl ::std::fmt::Display for InputItemType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for InputItemType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct BaseProperties { pub model: String, diff --git a/src/snapshots/openapi_to_rust__test_helpers__debug_test.snap b/src/snapshots/openapi_to_rust__test_helpers__debug_test.snap index c478327..5be669d 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__debug_test.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__debug_test.snap @@ -21,3 +21,20 @@ pub enum TypedEventType { #[serde(rename = "event.created")] EventCreated, } +impl TypedEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::EventCreated => "event.created", + } + } +} +impl ::std::fmt::Display for TypedEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TypedEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__discriminator_no_mapping.snap b/src/snapshots/openapi_to_rust__test_helpers__discriminator_no_mapping.snap index 36aadf1..d4b9d61 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__discriminator_no_mapping.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__discriminator_no_mapping.snap @@ -29,6 +29,23 @@ pub enum DogSpecies { #[serde(rename = "dog")] Dog, } +impl DogSpecies { + pub fn as_str(&self) -> &'static str { + match self { + Self::Dog => "dog", + } + } +} +impl ::std::fmt::Display for DogSpecies { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for DogSpecies { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Cat { pub meow: bool, @@ -39,3 +56,20 @@ pub enum CatSpecies { #[serde(rename = "cat")] Cat, } +impl CatSpecies { + pub fn as_str(&self) -> &'static str { + match self { + Self::Cat => "cat", + } + } +} +impl ::std::fmt::Display for CatSpecies { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for CatSpecies { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__duplicate_discriminator_values.snap b/src/snapshots/openapi_to_rust__test_helpers__duplicate_discriminator_values.snap index b95b7af..ef67193 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__duplicate_discriminator_values.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__duplicate_discriminator_values.snap @@ -29,6 +29,23 @@ pub enum SimpleTextType { #[serde(rename = "text")] Text, } +impl SimpleTextType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Text => "text", + } + } +} +impl ::std::fmt::Display for SimpleTextType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for SimpleTextType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct RichText { pub html: String, @@ -41,3 +58,20 @@ pub enum RichTextType { #[serde(rename = "text")] Text, } +impl RichTextType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Text => "text", + } + } +} +impl ::std::fmt::Display for RichTextType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for RichTextType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__enum_properties.snap b/src/snapshots/openapi_to_rust__test_helpers__enum_properties.snap index 0cf41d8..76e57b9 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__enum_properties.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__enum_properties.snap @@ -27,15 +27,68 @@ pub enum SimpleMessageStatus { #[serde(rename = "pending")] Pending, } +impl SimpleMessageStatus { + pub fn as_str(&self) -> &'static str { + match self { + Self::Active => "active", + Self::Inactive => "inactive", + Self::Pending => "pending", + } + } +} +impl ::std::fmt::Display for SimpleMessageStatus { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for SimpleMessageStatus { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)] pub enum SimpleMessageRole { #[default] #[serde(rename = "assistant")] Assistant, } +impl SimpleMessageRole { + pub fn as_str(&self) -> &'static str { + match self { + Self::Assistant => "assistant", + } + } +} +impl ::std::fmt::Display for SimpleMessageRole { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for SimpleMessageRole { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)] pub enum RoleEnum { #[default] #[serde(rename = "assistant")] Assistant, } +impl RoleEnum { + pub fn as_str(&self) -> &'static str { + match self { + Self::Assistant => "assistant", + } + } +} +impl ::std::fmt::Display for RoleEnum { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for RoleEnum { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__ideal_const_enum.snap b/src/snapshots/openapi_to_rust__test_helpers__ideal_const_enum.snap index d699ef3..34f65af 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__ideal_const_enum.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__ideal_const_enum.snap @@ -50,3 +50,20 @@ pub enum SingleValueEnum { #[serde(rename = "fixed_value")] FixedValue, } +impl SingleValueEnum { + pub fn as_str(&self) -> &'static str { + match self { + Self::FixedValue => "fixed_value", + } + } +} +impl ::std::fmt::Display for SingleValueEnum { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for SingleValueEnum { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__inline_enum_collision_nesting.snap b/src/snapshots/openapi_to_rust__test_helpers__inline_enum_collision_nesting.snap index f099f3f..8044a92 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__inline_enum_collision_nesting.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__inline_enum_collision_nesting.snap @@ -26,6 +26,23 @@ pub enum PlanDataTypePlans { #[serde(rename = "plans")] Plans, } +impl PlanDataTypePlans { + pub fn as_str(&self) -> &'static str { + match self { + Self::Plans => "plans", + } + } +} +impl ::std::fmt::Display for PlanDataTypePlans { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for PlanDataTypePlans { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct PlanDataAttributes { #[serde(skip_serializing_if = "Option::is_none")] @@ -51,3 +68,22 @@ pub enum PlanDataType { #[serde(rename = "NVME")] Nvme, } +impl PlanDataType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Ssd => "SSD", + Self::Hdd => "HDD", + Self::Nvme => "NVME", + } + } +} +impl ::std::fmt::Display for PlanDataType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for PlanDataType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__inline_enum_dedup_identical_values.snap b/src/snapshots/openapi_to_rust__test_helpers__inline_enum_dedup_identical_values.snap index 349b42b..5f3d8fd 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__inline_enum_dedup_identical_values.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__inline_enum_dedup_identical_values.snap @@ -26,6 +26,25 @@ pub enum TaskStatus { #[serde(rename = "done")] Done, } +impl TaskStatus { + pub fn as_str(&self) -> &'static str { + match self { + Self::Queued => "queued", + Self::Running => "running", + Self::Done => "done", + } + } +} +impl ::std::fmt::Display for TaskStatus { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TaskStatus { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Job { #[serde(skip_serializing_if = "Option::is_none")] @@ -41,3 +60,22 @@ pub enum JobStatus { #[serde(rename = "done")] Done, } +impl JobStatus { + pub fn as_str(&self) -> &'static str { + match self { + Self::Queued => "queued", + Self::Running => "running", + Self::Done => "done", + } + } +} +impl ::std::fmt::Display for JobStatus { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for JobStatus { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__inline_enum_extraction.snap b/src/snapshots/openapi_to_rust__test_helpers__inline_enum_extraction.snap index bb97e5c..cb5778d 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__inline_enum_extraction.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__inline_enum_extraction.snap @@ -28,3 +28,22 @@ pub enum MessageRole { #[serde(rename = "system")] System, } +impl MessageRole { + pub fn as_str(&self) -> &'static str { + match self { + Self::User => "user", + Self::Assistant => "assistant", + Self::System => "system", + } + } +} +impl ::std::fmt::Display for MessageRole { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for MessageRole { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__mixed_inline_ref_oneof.snap b/src/snapshots/openapi_to_rust__test_helpers__mixed_inline_ref_oneof.snap index 9b2aee6..e6a6c44 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__mixed_inline_ref_oneof.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__mixed_inline_ref_oneof.snap @@ -31,6 +31,23 @@ pub enum UrlBlockType { #[serde(rename = "redirect")] Redirect, } +impl UrlBlockType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Redirect => "redirect", + } + } +} +impl ::std::fmt::Display for UrlBlockType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for UrlBlockType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct NamedError { pub code: String, @@ -42,6 +59,23 @@ pub enum NamedErrorType { #[serde(rename = "error")] Error, } +impl NamedErrorType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Error => "error", + } + } +} +impl ::std::fmt::Display for NamedErrorType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for NamedErrorType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct DataBlock { pub data: serde_json::Value, @@ -52,3 +86,20 @@ pub enum DataBlockType { #[serde(rename = "success")] Success, } +impl DataBlockType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Success => "success", + } + } +} +impl ::std::fmt::Display for DataBlockType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for DataBlockType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__multiple_enum_properties.snap b/src/snapshots/openapi_to_rust__test_helpers__multiple_enum_properties.snap index 43e4352..bc086c9 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__multiple_enum_properties.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__multiple_enum_properties.snap @@ -31,6 +31,25 @@ pub enum TaskType { #[serde(rename = "deploy")] Deploy, } +impl TaskType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Build => "build", + Self::Test => "test", + Self::Deploy => "deploy", + } + } +} +impl ::std::fmt::Display for TaskType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TaskType { + fn as_ref(&self) -> &str { + self.as_str() + } +} ///Task status #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)] pub enum TaskStatus { @@ -44,6 +63,26 @@ pub enum TaskStatus { #[serde(rename = "failed")] Failed, } +impl TaskStatus { + pub fn as_str(&self) -> &'static str { + match self { + Self::Pending => "pending", + Self::Running => "running", + Self::Completed => "completed", + Self::Failed => "failed", + } + } +} +impl ::std::fmt::Display for TaskStatus { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TaskStatus { + fn as_ref(&self) -> &str { + self.as_str() + } +} ///Task priority #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)] pub enum TaskPriority { @@ -57,3 +96,23 @@ pub enum TaskPriority { #[serde(rename = "critical")] Critical, } +impl TaskPriority { + pub fn as_str(&self) -> &'static str { + match self { + Self::Low => "low", + Self::Medium => "medium", + Self::High => "high", + Self::Critical => "critical", + } + } +} +impl ::std::fmt::Display for TaskPriority { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TaskPriority { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__oneof_in_property.snap b/src/snapshots/openapi_to_rust__test_helpers__oneof_in_property.snap index 030a656..9814e7a 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__oneof_in_property.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__oneof_in_property.snap @@ -26,12 +26,46 @@ pub enum URLImageSourceType { #[serde(rename = "url")] Url, } +impl URLImageSourceType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Url => "url", + } + } +} +impl ::std::fmt::Display for URLImageSourceType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for URLImageSourceType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Default)] pub enum ImageBlockType { #[default] #[serde(rename = "image")] Image, } +impl ImageBlockType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Image => "image", + } + } +} +impl ::std::fmt::Display for ImageBlockType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ImageBlockType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(tag = "type")] pub enum ImageBlockSource { @@ -50,3 +84,20 @@ pub enum Base64ImageSourceType { #[serde(rename = "base64")] Base64, } +impl Base64ImageSourceType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Base64 => "base64", + } + } +} +impl ::std::fmt::Display for Base64ImageSourceType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for Base64ImageSourceType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__property_underscore_types.snap b/src/snapshots/openapi_to_rust__test_helpers__property_underscore_types.snap index 3f036c9..751bf5c 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__property_underscore_types.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__property_underscore_types.snap @@ -30,6 +30,23 @@ pub enum ConfigObjectCacheControl { #[serde(rename = "ephemeral")] Ephemeral, } +impl ConfigObjectCacheControl { + pub fn as_str(&self) -> &'static str { + match self { + Self::Ephemeral => "ephemeral", + } + } +} +impl ::std::fmt::Display for ConfigObjectCacheControl { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ConfigObjectCacheControl { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct HeightBlock { pub height: i64, diff --git a/src/snapshots/openapi_to_rust__test_helpers__type_property_only_test.snap b/src/snapshots/openapi_to_rust__test_helpers__type_property_only_test.snap index c478327..5be669d 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__type_property_only_test.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__type_property_only_test.snap @@ -21,3 +21,20 @@ pub enum TypedEventType { #[serde(rename = "event.created")] EventCreated, } +impl TypedEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::EventCreated => "event.created", + } + } +} +impl ::std::fmt::Display for TypedEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for TypedEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__underscore_type_names.snap b/src/snapshots/openapi_to_rust__test_helpers__underscore_type_names.snap index 81fbff1..173450f 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__underscore_type_names.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__underscore_type_names.snap @@ -29,6 +29,23 @@ pub enum ResponseCreatedEventType { #[serde(rename = "created")] Created, } +impl ResponseCreatedEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Created => "created", + } + } +} +impl ::std::fmt::Display for ResponseCreatedEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseCreatedEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ResponseCompletedEvent { pub id: String, @@ -39,6 +56,23 @@ pub enum ResponseCompletedEventType { #[serde(rename = "completed")] Completed, } +impl ResponseCompletedEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::Completed => "completed", + } + } +} +impl ::std::fmt::Display for ResponseCompletedEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseCompletedEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct BetaListResponseMessageBatch { pub id: String, @@ -53,3 +87,20 @@ pub enum BetaTool20241022CacheControl { #[serde(rename = "ephemeral")] Ephemeral, } +impl BetaTool20241022CacheControl { + pub fn as_str(&self) -> &'static str { + match self { + Self::Ephemeral => "ephemeral", + } + } +} +impl ::std::fmt::Display for BetaTool20241022CacheControl { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for BetaTool20241022CacheControl { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__x_stainless_const_bug.snap b/src/snapshots/openapi_to_rust__test_helpers__x_stainless_const_bug.snap index fb39425..df0fbe7 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__x_stainless_const_bug.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__x_stainless_const_bug.snap @@ -32,6 +32,25 @@ pub enum ResponseReasoningSummaryPartDoneEventType { #[serde(rename = "response.reasoning_summary_part.done")] ResponseReasoningSummaryPartDone, } +impl ResponseReasoningSummaryPartDoneEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::ResponseReasoningSummaryPartDone => { + "response.reasoning_summary_part.done" + } + } + } +} +impl ::std::fmt::Display for ResponseReasoningSummaryPartDoneEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseReasoningSummaryPartDoneEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} ///Emitted when a new reasoning summary part is added. #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ResponseReasoningSummaryPartAddedEvent { @@ -45,6 +64,25 @@ pub enum ResponseReasoningSummaryPartAddedEventType { #[serde(rename = "response.reasoning_summary_part.added")] ResponseReasoningSummaryPartAdded, } +impl ResponseReasoningSummaryPartAddedEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::ResponseReasoningSummaryPartAdded => { + "response.reasoning_summary_part.added" + } + } + } +} +impl ::std::fmt::Display for ResponseReasoningSummaryPartAddedEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseReasoningSummaryPartAddedEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ReasoningItem { pub text: String, @@ -58,3 +96,20 @@ pub enum ReasoningItemType { #[serde(rename = "summary_text")] SummaryText, } +impl ReasoningItemType { + pub fn as_str(&self) -> &'static str { + match self { + Self::SummaryText => "summary_text", + } + } +} +impl ::std::fmt::Display for ReasoningItemType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ReasoningItemType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__x_stainless_discriminated.snap b/src/snapshots/openapi_to_rust__test_helpers__x_stainless_discriminated.snap index b383461..44ff5cf 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__x_stainless_discriminated.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__x_stainless_discriminated.snap @@ -30,6 +30,25 @@ pub enum ResponseReasoningSummaryPartDoneEventType { #[serde(rename = "response.reasoning_summary_part.done")] ResponseReasoningSummaryPartDone, } +impl ResponseReasoningSummaryPartDoneEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::ResponseReasoningSummaryPartDone => { + "response.reasoning_summary_part.done" + } + } + } +} +impl ::std::fmt::Display for ResponseReasoningSummaryPartDoneEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseReasoningSummaryPartDoneEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ResponseReasoningSummaryPartAddedEvent { pub part: ReasoningPart, @@ -41,6 +60,25 @@ pub enum ResponseReasoningSummaryPartAddedEventType { #[serde(rename = "response.reasoning_summary_part.added")] ResponseReasoningSummaryPartAdded, } +impl ResponseReasoningSummaryPartAddedEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::ResponseReasoningSummaryPartAdded => { + "response.reasoning_summary_part.added" + } + } + } +} +impl ::std::fmt::Display for ResponseReasoningSummaryPartAddedEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseReasoningSummaryPartAddedEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ReasoningPart { pub text: String, @@ -54,3 +92,20 @@ pub enum ReasoningPartType { #[serde(rename = "summary_text")] SummaryText, } +impl ReasoningPartType { + pub fn as_str(&self) -> &'static str { + match self { + Self::SummaryText => "summary_text", + } + } +} +impl ::std::fmt::Display for ReasoningPartType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ReasoningPartType { + fn as_ref(&self) -> &str { + self.as_str() + } +} diff --git a/src/snapshots/openapi_to_rust__test_helpers__x_stainless_nested.snap b/src/snapshots/openapi_to_rust__test_helpers__x_stainless_nested.snap index 01efe06..47a12af 100644 --- a/src/snapshots/openapi_to_rust__test_helpers__x_stainless_nested.snap +++ b/src/snapshots/openapi_to_rust__test_helpers__x_stainless_nested.snap @@ -24,6 +24,23 @@ pub enum ResponseEventType { #[serde(rename = "response.event.done")] ResponseEventDone, } +impl ResponseEventType { + pub fn as_str(&self) -> &'static str { + match self { + Self::ResponseEventDone => "response.event.done", + } + } +} +impl ::std::fmt::Display for ResponseEventType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ResponseEventType { + fn as_ref(&self) -> &str { + self.as_str() + } +} #[derive(Debug, Clone, Deserialize, Serialize)] pub struct ReasoningPart { pub text: String, @@ -37,3 +54,20 @@ pub enum ReasoningPartType { #[serde(rename = "summary_text")] SummaryText, } +impl ReasoningPartType { + pub fn as_str(&self) -> &'static str { + match self { + Self::SummaryText => "summary_text", + } + } +} +impl ::std::fmt::Display for ReasoningPartType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.write_str(self.as_str()) + } +} +impl AsRef for ReasoningPartType { + fn as_ref(&self) -> &str { + self.as_str() + } +}