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>,

我正在Rust中构建一个库,它有一个
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
就是我想要的-这是不可能的:。我不确定我是否理解。当您发出请求(call
send
)时,您是否提前知道响应(如果成功)是否包含数据?或者您在不知道是否会实际返回
R
的情况下发出请求?我事先知道将返回哪些类型,或者是我想要的类型,或者是错误。即使对于成功不返回任何内容的请求,错误也会返回带有错误消息的JSON。
send
有效吗?如果调用方知道它期望的是“nothing”,那么它不应该告诉
send
反序列化为“某物”。我想返回类型
EmptyResponse
就是我想要的-这是不可能的:。我不确定我是否理解。当您发出请求(call
send
)时,您是否提前知道响应(如果成功)是否包含数据?或者你提出的要求不是
#![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");
}