fix: make operation marker naming total
This commit is contained in:
@@ -473,7 +473,7 @@ fn normalize_operation(method: &mut TraitItemFn) -> syn::Result<Operation> {
|
||||
}
|
||||
|
||||
Ok(Operation {
|
||||
marker_ident: format_ident!("{}", to_pascal_case(&method.sig.ident)),
|
||||
marker_ident: operation_marker_ident(&method.sig.ident),
|
||||
method_ident: method.sig.ident.clone(),
|
||||
operation_id,
|
||||
method: http_method,
|
||||
@@ -926,6 +926,21 @@ fn ident_text(ident: &Ident) -> String {
|
||||
value.strip_prefix("r#").unwrap_or(&value).to_owned()
|
||||
}
|
||||
|
||||
fn operation_marker_ident(method: &Ident) -> Ident {
|
||||
let candidate = to_pascal_case(method);
|
||||
if let Ok(mut marker) = syn::parse_str::<Ident>(&candidate) {
|
||||
marker.set_span(method.span());
|
||||
return marker;
|
||||
}
|
||||
|
||||
let encoded = ident_text(method)
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
.collect::<String>();
|
||||
Ident::new(&format!("Operation{encoded}"), method.span())
|
||||
}
|
||||
|
||||
fn to_pascal_case(ident: &Ident) -> String {
|
||||
ident_text(ident)
|
||||
.split('_')
|
||||
|
||||
@@ -51,8 +51,9 @@
|
||||
//! For `WidgetApi`, the macro emits `WidgetApiMetadata`, which implements [`ApiContract`],
|
||||
//! plus a `widget_api_operations` module. That module contains one marker per Rust method
|
||||
//! (`Create`, `Get`, ...), each implementing [`Operation`] and connecting metadata to concrete
|
||||
//! body types at compile time. The `ApiContract::OPERATIONS` inventory is sorted by operation
|
||||
//! ID, so its ordering is independent of source method order.
|
||||
//! body types at compile time. Unusual method names which have no valid PascalCase form use the
|
||||
//! deterministic `Operation<utf8-hex>` fallback. The `ApiContract::OPERATIONS` inventory is
|
||||
//! sorted by operation ID, so its ordering is independent of source method order.
|
||||
//!
|
||||
//! Only empty and JSON bodies are accepted by this first contract. [`WireKind`] reserves
|
||||
//! explicit variants for future transport work; accepting one requires a deliberate macro and
|
||||
|
||||
@@ -41,6 +41,15 @@ pub trait RawIdentifierApi {
|
||||
async fn r#type(&self) -> Widget;
|
||||
}
|
||||
|
||||
#[api]
|
||||
pub trait UnusualIdentifierApi {
|
||||
#[get("/underscores", operation_id = "unusual.underscores")]
|
||||
async fn __(&self) -> Widget;
|
||||
|
||||
#[get("/underscore-digit", operation_id = "unusual.underscore_digit")]
|
||||
async fn _0(&self) -> Widget;
|
||||
}
|
||||
|
||||
fn assert_operation_types<O>()
|
||||
where
|
||||
O: Operation<
|
||||
@@ -60,6 +69,11 @@ fn expansion_exposes_deterministic_metadata_and_type_connections() {
|
||||
assert_named_wrapper::<wrapper_api_operations::Search>();
|
||||
let raw = <raw_identifier_api_operations::Type as Operation>::METADATA;
|
||||
assert_eq!(raw.operation_id, "raw.type");
|
||||
let underscores = <unusual_identifier_api_operations::Operation5f5f as Operation>::METADATA;
|
||||
assert_eq!(underscores.operation_id, "unusual.underscores");
|
||||
let underscore_digit =
|
||||
<unusual_identifier_api_operations::Operation5f30 as Operation>::METADATA;
|
||||
assert_eq!(underscore_digit.operation_id, "unusual.underscore_digit");
|
||||
|
||||
let operations = <WidgetApiMetadata as ApiContract>::OPERATIONS;
|
||||
assert_eq!(operations.len(), 3);
|
||||
|
||||
Reference in New Issue
Block a user