diff --git a/dxr_derive/src/lib.rs b/dxr_derive/src/lib.rs index 6b6762a..fef555e 100644 --- a/dxr_derive/src/lib.rs +++ b/dxr_derive/src/lib.rs @@ -102,6 +102,10 @@ pub fn try_from_value(input: TokenStream) -> TokenStream { }.into(), }; let ident_str = ident.to_string(); + let ident_str = match ident_str.strip_prefix("r#") { + Some(s) => s, + None => ident_str.as_str(), + }; field_impls.push(quote! { #ident: <#stype as TryFromValue>::try_from_value(map.get(#ident_str) .ok_or_else(|| #dxr::DxrError::missing_field(#name_str, #ident_str))?)?, @@ -213,6 +217,10 @@ pub fn try_to_value(input: TokenStream) -> TokenStream { }, }; let ident_str = ident.to_string(); + let ident_str = match ident_str.strip_prefix("r#") { + Some(s) => s, + None => ident_str.as_str(), + }; field_impls.push(quote! { map.insert(String::from(#ident_str), <#stype as TryToValue>::try_to_value(&self.#ident)?); }); diff --git a/dxr_tests/tests/echo_any.rs b/dxr_tests/tests/echo_any.rs index 2c6bba6..67afd5a 100644 --- a/dxr_tests/tests/echo_any.rs +++ b/dxr_tests/tests/echo_any.rs @@ -1,6 +1,7 @@ //! This file implements a test that launches a simple echo server, which is then used for roundtrip //! tests with different types of values, including custom structs. +use std::borrow::Cow; use std::collections::HashMap; use std::time::Duration; @@ -159,6 +160,80 @@ async fn echo() { let r: Octuple = client.call(call).await.unwrap(); assert_eq!(value, r); + // missing field + { + #[derive(TryToValue)] + struct Params { + foo: i32, + bar: i32, + } + #[allow(dead_code)] + #[derive(TryFromValue, Debug)] + struct Response { + foo: i32, + baz: i32, + } + let value = Params { foo: 1, bar: 2 }; + let call: Call<'_, _, (Response,)> = Call::new("echo", (value,)); + assert!(matches!( + client.call(call).await.unwrap_err(), + ClientError::RPC { + error: DxrError::MissingField { + name: Cow::Borrowed("Response"), + field: Cow::Borrowed("baz") + } + } + )); + } + + // escaped field in params + { + #[derive(TryToValue)] + struct Params { + r#foo: i32, + } + #[derive(Eq, PartialEq, TryFromValue, Debug)] + struct Response { + foo: i32, + } + let value = Params { foo: 1 }; + let call = Call::new("echo", (value,)); + let r: (Response,) = client.call(call).await.unwrap(); + assert_eq!(r, (Response { foo: 1 },)); + } + + // escaped field in response + { + #[derive(TryToValue)] + struct Params { + foo: i32, + } + #[derive(Eq, PartialEq, TryFromValue, Debug)] + struct Response { + r#foo: i32, + } + let value = Params { foo: 1 }; + let call = Call::new("echo", (value,)); + let r: (Response,) = client.call(call).await.unwrap(); + assert_eq!(r, (Response { foo: 1 },)); + } + + // escaped field in params & response + { + #[derive(TryToValue)] + struct Params { + r#type: i32, + } + #[derive(Eq, PartialEq, TryFromValue, Debug)] + struct Response { + r#type: i32, + } + let value = Params { r#type: 1 }; + let call = Call::new("echo", (value,)); + let r: (Response,) = client.call(call).await.unwrap(); + assert_eq!(r, (Response { r#type: 1 },)); + } + // type mismatch let value = -12i32; let call: Call<(i32,), (String,)> = Call::new("echo", (value,));