Skip to content

Commit 623220a

Browse files
committed
fix: pr review comments
1 parent bc6ee18 commit 623220a

5 files changed

Lines changed: 34 additions & 12 deletions

File tree

crates/oapi-codegen/src/emit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ fn emit_type(ty: &RustType) -> Result<TokenStream> {
258258
quote! { #ident }
259259
}
260260
RustType::External { module, name } => {
261-
let path: TokenStream = module.parse().map_err(|_| {
261+
let path: syn::Path = syn::parse_str(module).map_err(|_| {
262262
return Error::UnsupportedSchema {
263263
path: "import-mapping".to_owned(),
264264
reason: format!("module path `{module}` is not a valid Rust path expression"),

crates/oapi-codegen/src/loader.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ impl Spec {
8080
pub fn resolve_response(&self, reference: &str) -> Result<&Response> {
8181
let mut current = reference.to_owned();
8282
for _ in 0..MAX_REF_DEPTH {
83+
if ref_file_part(&current).is_some() {
84+
return Err(Error::UnsupportedRef {
85+
reference: current.clone(),
86+
reason: "cross-file component response `$ref`s are not supported".to_owned(),
87+
});
88+
}
8389
let name = ref_component_name(&current, "responses").ok_or_else(|| {
8490
return Error::UnsupportedRef {
8591
reference: current.clone(),

crates/oapi-codegen/src/paths.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl Lowerer<'_> {
125125
for name in path_param_names(path) {
126126
let declared = find_path_param(&name, operation, shared_params);
127127
let ty = match declared {
128-
Some(format) => self.param_type(path, &name, format)?,
128+
Some(format) => self.param_type(path, method, &name, format)?,
129129
None => RustType::String,
130130
};
131131
params.push(Param {
@@ -166,19 +166,19 @@ fn path_param_schema<'a>(name: &str, parameters: &'a [ReferenceOr<Parameter>]) -
166166

167167
/// Map a path parameter's schema to a scalar Rust type.
168168
impl Lowerer<'_> {
169-
fn param_type(&self, path: &str, name: &str, format: &ParameterSchemaOrContent) -> Result<RustType> {
169+
fn param_type(&self, path: &str, method: &str, name: &str, format: &ParameterSchemaOrContent) -> Result<RustType> {
170170
let schema = match format {
171171
ParameterSchemaOrContent::Schema(schema) => schema,
172172
ParameterSchemaOrContent::Content(_) => {
173173
return Err(Error::UnsupportedOperation {
174-
method: "*".to_owned(),
174+
method: method.to_owned(),
175175
path: path.to_owned(),
176176
reason: format!("path parameter `{name}` uses `content`, which is not supported"),
177177
});
178178
}
179179
};
180180
let schema = match schema {
181-
ReferenceOr::Reference { reference } => return self.named_from_ref(path, reference),
181+
ReferenceOr::Reference { reference } => return self.named_from_ref(path, method, reference),
182182
ReferenceOr::Item(schema) => schema,
183183
};
184184
let ty = match &schema.schema_kind {
@@ -188,7 +188,7 @@ impl Lowerer<'_> {
188188
SchemaKind::Type(Type::Boolean(_)) => RustType::Bool,
189189
_ => {
190190
return Err(Error::UnsupportedOperation {
191-
method: "*".to_owned(),
191+
method: method.to_owned(),
192192
path: path.to_owned(),
193193
reason: format!("path parameter `{name}` must be a scalar type"),
194194
});
@@ -291,7 +291,7 @@ impl Lowerer<'_> {
291291
/// their emission.
292292
fn body_type(&self, path: &str, method: &str, schema: &ReferenceOr<Schema>) -> Result<RustType> {
293293
match schema {
294-
ReferenceOr::Reference { reference } => return self.named_from_ref(path, reference),
294+
ReferenceOr::Reference { reference } => return self.named_from_ref(path, method, reference),
295295
ReferenceOr::Item(schema) => return self.inline_body_type(path, method, schema),
296296
}
297297
}
@@ -305,7 +305,7 @@ impl Lowerer<'_> {
305305
SchemaKind::Type(Type::Boolean(_)) => RustType::Bool,
306306
SchemaKind::Type(Type::Array(at)) => {
307307
let element = match &at.items {
308-
Some(ReferenceOr::Reference { reference }) => self.named_from_ref(path, reference)?,
308+
Some(ReferenceOr::Reference { reference }) => self.named_from_ref(path, method, reference)?,
309309
Some(ReferenceOr::Item(item)) => self.inline_body_type(path, method, item)?,
310310
None => RustType::Value,
311311
};
@@ -326,10 +326,10 @@ impl Lowerer<'_> {
326326
/// Resolve a `$ref` string to a named type. Same-document references become
327327
/// a local [`RustType::Named`]; cross-file references are routed through the
328328
/// `import-mapping` to a [`RustType::External`].
329-
fn named_from_ref(&self, path: &str, reference: &str) -> Result<RustType> {
329+
fn named_from_ref(&self, path: &str, method: &str, reference: &str) -> Result<RustType> {
330330
let target = ref_target_name(reference).ok_or_else(|| {
331331
return Error::UnsupportedOperation {
332-
method: "*".to_owned(),
332+
method: method.to_owned(),
333333
path: path.to_owned(),
334334
reason: format!("reference `{reference}` must point at a component schema"),
335335
};
@@ -339,7 +339,7 @@ impl Lowerer<'_> {
339339
};
340340
let module = self.import_mapping.get(file).ok_or_else(|| {
341341
return Error::UnsupportedOperation {
342-
method: "*".to_owned(),
342+
method: method.to_owned(),
343343
path: path.to_owned(),
344344
reason: format!("cross-file reference `{reference}` needs an `import-mapping` entry for `{file}`"),
345345
};

crates/oapi-codegen/tests/coverage.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,11 @@ const SERVER_FIXTURES: &[&str] = &["server_petstore", "server_refs"];
333333

334334
/// Server fixtures whose generation must fail with a documented error, covering
335335
/// the slice's deliberate limitations (e.g. `default`/range responses).
336-
const SERVER_UNSUPPORTED_FIXTURES: &[&str] = &["server_unsupported_default_response", "server_unsupported_ref_param"];
336+
const SERVER_UNSUPPORTED_FIXTURES: &[&str] = &[
337+
"server_unsupported_default_response",
338+
"server_unsupported_ref_param",
339+
"server_unsupported_xfile_response_ref",
340+
];
337341

338342
/// Absolute path to the crate's `tests` directory.
339343
fn tests_dir() -> PathBuf {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.0.3
2+
info:
3+
title: Cross-file response ref server
4+
version: 1.0.0
5+
paths:
6+
/widgets:
7+
get:
8+
operationId: listWidgets
9+
summary: List widgets.
10+
responses:
11+
"401":
12+
$ref: "schemas/common.yaml#/components/responses/Unauthorized"

0 commit comments

Comments
 (0)