Rust 如果没有可返回的内容,如何从泛型函数返回有意义的内容?
我正在Rust中构建一个库,它有一个Rust 如果没有可返回的内容,如何从泛型函数返回有意义的内容?,rust,serde-json,Rust,Serde Json,我正在Rust中构建一个库,它有一个send方法,使用reqwest对本地RPC服务器执行HTTP请求 此方法在结果中返回泛型类型R,其中R:DeserializeOwned。为每个响应生成正确的类型后,serde\u json::from\u str()可以为我获取类型 如果请求没有响应,如何使send仍然返回有意义的内容 这是我现在拥有的代码: fn send<R, T>( &self, request: &RpcRequest<T>,
send
方法,使用reqwest对本地RPC服务器执行HTTP请求
此方法在结果中返回泛型类型R
,其中R:DeserializeOwned
。为每个响应生成正确的类型后,serde\u json::from\u str()
可以为我获取类型
如果请求没有响应,如何使send
仍然返回有意义的内容
这是我现在拥有的代码:
fn send<R, T>(
&self,
request: &RpcRequest<T>,
) -> Result<R, ApiError>
where
T: Serialize + Debug,
R: DeserializeOwned + Debug,
我现在被迫创建并返回一个错误
,但从技术上讲,不返回响应的请求是预期行为,因此我想返回除错误
之外的其他内容
我试图通过使用选项
包装R
来解决这一问题,但这意味着我必须加倍打开每个响应,reqwest的98%响应中都有数据,所以感觉有点像是过火了
我还试图返回一个自制的EmptyResponse
类型,但编译器抱怨:预期的类型是R,找到的类型是EmptyResponse
。我想返回一个类型EmptyResponse
就是我想要的,但是也许有人可以提供一些技巧,告诉我如何做得更好。您可以返回一个结果,如中所示,然后像这样匹配它:
匹配发件人。发送(请求){
好的(一些(r))=>{
//过程响应
}
正常(无)=>{
//处理空响应
}
错误(e)=>{
//过程错误
}
}
//或
如果让Ok(Some(r))=发送方发送(请求){
//过程响应
}
我试图通过使用选项
包装R
来解决这一问题,但这意味着我必须加倍打开每个响应,reqwest的98%响应中都有数据,所以感觉有点像是过火了
展开选项
是一项非常便宜的操作,无需担心。您可以返回结果
,如中所示,然后按如下方式进行匹配:
匹配发件人。发送(请求){
好的(一些(r))=>{
//过程响应
}
正常(无)=>{
//处理空响应
}
错误(e)=>{
//过程错误
}
}
//或
如果让Ok(Some(r))=发送方发送(请求){
//过程响应
}
我试图通过使用选项
包装R
来解决这一问题,但这意味着我必须加倍打开每个响应,reqwest的98%响应中都有数据,所以感觉有点像是过火了
展开选项
是一个非常便宜的操作,没有什么可担心的。实用的答案是有两个功能:
fn send<R, T>(&self, request: &RpcRequest<T>) -> Result<R, ApiError>
where
T: Serialize + Debug,
R: DeserializeOwned + Debug,
这种恐慌:
无法反序列化:错误(“解析值时的EOF”,第1行,第0列)
在一个专业化的世界中,您可以使用它和一个助手特性将其缩减为一个函数:
#![feature(specialization)]
use serde::de::DeserializeOwned; // 1.0.85
use serde_json; // 1.0.37
type Error = Box<std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;
type ApiResponse = &'static str;
trait FromApi: Sized {
fn convert(response: ApiResponse) -> Result<Self, Error>;
}
impl<R> FromApi for R
where
R: DeserializeOwned,
{
default fn convert(response: ApiResponse) -> Result<R, Error> {
eprintln!("deserializing the response");
serde_json::from_str(response).map_err(Into::into)
}
}
impl FromApi for () {
fn convert(_response: ApiResponse) -> Result<Self, Error> {
eprintln!("Ignoring the response");
Ok(())
}
}
fn send<R: FromApi>() -> Result<R> {
eprintln!(r#""sending" the request"#);
let api_response = "";
R::convert(api_response)
}
fn main() {
let _r: () = send().expect("Unable to deserialize");
}
#![专题(专门化)]
使用serde::de::反序列化拥有;//1.0.85
使用serde_json;//1.0.37
类型错误=框;
类型Result=std::Result::Result;
类型ApiResponse=&'static str;
来自API的特征:大小{
fn转换(响应:ApiResponse)->结果;
}
针对R的impl-FromApi
哪里
R:反序列化,
{
默认fn转换(响应:ApiResponse)->结果{
eprintln!(“反序列化响应”);
serde_json::from_str(response).map_err(Into::Into)
}
}
针对()的impl FromApi{
fn转换(_响应:ApiResponse)->结果{
eprintln!(“忽略响应”);
好(())
}
}
fn send()->结果{
eprintln!(r#“发送”请求“#”);
让api_回应=”;
R::转换(api\U响应)
}
fn main(){
让_r:()=send().expect(“无法反序列化”);
}
实用的答案是有两个功能:
fn send<R, T>(&self, request: &RpcRequest<T>) -> Result<R, ApiError>
where
T: Serialize + Debug,
R: DeserializeOwned + Debug,
这种恐慌:
无法反序列化:错误(“解析值时的EOF”,第1行,第0列)
在一个专业化的世界中,您可以使用它和一个助手特性将其缩减为一个函数:
#![feature(specialization)]
use serde::de::DeserializeOwned; // 1.0.85
use serde_json; // 1.0.37
type Error = Box<std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;
type ApiResponse = &'static str;
trait FromApi: Sized {
fn convert(response: ApiResponse) -> Result<Self, Error>;
}
impl<R> FromApi for R
where
R: DeserializeOwned,
{
default fn convert(response: ApiResponse) -> Result<R, Error> {
eprintln!("deserializing the response");
serde_json::from_str(response).map_err(Into::into)
}
}
impl FromApi for () {
fn convert(_response: ApiResponse) -> Result<Self, Error> {
eprintln!("Ignoring the response");
Ok(())
}
}
fn send<R: FromApi>() -> Result<R> {
eprintln!(r#""sending" the request"#);
let api_response = "";
R::convert(api_response)
}
fn main() {
let _r: () = send().expect("Unable to deserialize");
}
#![专题(专门化)]
使用serde::de::反序列化拥有;//1.0.85
使用serde_json;//1.0.37
类型错误=框;
类型Result=std::Result::Result;
类型ApiResponse=&'static str;
来自API的特征:大小{
fn转换(响应:ApiResponse)->结果;
}
针对R的impl-FromApi
哪里
R:反序列化,
{
默认fn转换(响应:ApiResponse)->结果{
eprintln!(“反序列化响应”);
serde_json::from_str(response).map_err(Into::Into)
}
}
针对()的impl FromApi{
fn转换(_响应:ApiResponse)->结果{
eprintln!(“忽略响应”);
好(())
}
}
fn send()->结果{
eprintln!(r#“发送”请求“#”);
让api_回应=”;
R::转换(api\U响应)
}
fn main(){
让_r:()=send().expect(“无法反序列化”);
}
我想返回类型EmptyResponse
就是我想要的-这是不可能的:。我不确定我是否理解。当您发出请求(callsend
)时,您是否提前知道响应(如果成功)是否包含数据?或者您在不知道是否会实际返回R
的情况下发出请求?我事先知道将返回哪些类型,或者是我想要的类型,或者是错误。即使对于成功不返回任何内容的请求,错误也会返回带有错误消息的JSON。send
有效吗?如果调用方知道它期望的是“nothing”,那么它不应该告诉send
反序列化为“某物”。我想返回类型EmptyResponse
就是我想要的-这是不可能的:。我不确定我是否理解。当您发出请求(callsend
)时,您是否提前知道响应(如果成功)是否包含数据?或者你提出的要求不是
#![feature(specialization)]
use serde::de::DeserializeOwned; // 1.0.85
use serde_json; // 1.0.37
type Error = Box<std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;
type ApiResponse = &'static str;
trait FromApi: Sized {
fn convert(response: ApiResponse) -> Result<Self, Error>;
}
impl<R> FromApi for R
where
R: DeserializeOwned,
{
default fn convert(response: ApiResponse) -> Result<R, Error> {
eprintln!("deserializing the response");
serde_json::from_str(response).map_err(Into::into)
}
}
impl FromApi for () {
fn convert(_response: ApiResponse) -> Result<Self, Error> {
eprintln!("Ignoring the response");
Ok(())
}
}
fn send<R: FromApi>() -> Result<R> {
eprintln!(r#""sending" the request"#);
let api_response = "";
R::convert(api_response)
}
fn main() {
let _r: () = send().expect("Unable to deserialize");
}