Bypass Parameter Type and URL Encoding for uri!
Macro
#2859
Unanswered
KartikSoneji
asked this question in
Questions
Replies: 1 comment 4 replies
-
First, I took a stab at making your example code generic over the inner type, and work for both path and query. use rocket::{
http::{
impl_from_uri_param_identity,
uri::fmt::{Formatter, FromUriParam, Part, UriDisplay},
},
request::FromParam,
};
use std::fmt::Display;
pub struct QueryParameterPlaceholder<T>(pub T);
impl<T: Display> Display for QueryParameterPlaceholder<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{{{}}}", self.0)
}
}
impl<P: Part, T: Display> UriDisplay<P> for QueryParameterPlaceholder<T> {
fn fmt(&self, f: &mut Formatter<P>) -> std::fmt::Result {
f.write_raw(format!("{{{}}}", self.0))
}
}
impl_from_uri_param_identity!((T: Display) QueryParameterPlaceholder<T>);
impl<'a, T: FromParam<'a> + Display> FromParam<'a> for QueryParameterPlaceholder<T> {
type Error = T::Error;
fn from_param(param: &'a str) -> Result<Self, Self::Error> {
T::from_param(param).map(Self)
}
}
#[get("/<code>")]
fn code(code: QueryParameterPlaceholder<&str>) {}
fn tmp() {
let _ = uri!(code(QueryParameterPlaceholder("data")));
} I don't know if it meets your use-case, but it should at least point you in the right direction. Second, I do agree that it might be useful to add support for this to the macro. This isn't likely to land before 0.6 (which already has a ton of breaking changes), so I'd recommend going with the work-around for now. Looking at the syntax, I think it makes sense to use raw strings, like |
Beta Was this translation helpful? Give feedback.
4 replies
# for free
to join this conversation on GitHub.
Already have an account?
# to comment
-
The
uri!
macro is great for constructing typesafe urls but at times it's useful to be able to bypass the type restrictions or the URL Encoding of the values.My particular usecase is there is a third party service that expects callback URLs of the form
https://example.com/?a={data1}&b={data2}
where
{data1}
and{data2}
are placeholders that the service fills in before making the callback.Now the issue is the service needs those placeholders to exactly match the format of
{identifier}
.URL encoding as
%7Bidentifier%7D
does not work.Additionally, non-string parameters can't even accept
"{identifier}"
.One workaround I'm experimenting with is creating a struct that implements
FromUriParam
andUriDisplay
.Usage:
I can't seem to make the implementation generic for all types or over
Path
andQuery
, but that might be because of my limited rust knowledge.(Maybe it's better to add another trait,
UriRawDisplay
, implement it for the same types asUriDisplay
, and allow other structs to implement as needed)It also isn't the cleanest implementation, I would prefer an extension to the macro, similar to
_
for default fields.For example something like
(
raw{}
overraw()
since it avoids the issue of having an in-scope function that happens to be namedraw
)Beta Was this translation helpful? Give feedback.
All reactions