rust - 基于条件如何将输出分配给匹配类型的变量
问题描述
我想修改一个上传异步文件的库,以便它可以“公开”或“通知”它是什么迭代,我的目标是防止直接从库中“打印/写入”,而是从方法中做到这一点使用该库,以便通过使用“暴露”的数据,他们可以做一些事情。我用于在每次交互中测试任务的代码是:
use futures::stream::TryStreamExt;
use tokio_util::codec::{BytesCodec, FramedRead};
let stream = FramedRead::new(file, BytesCodec::new())
.inspect_ok(|chunk| {
// do X with chunk...
});
// reqwest
let body = Body::wrap_stream(stream);
client.put(url).body(body)
我正在考虑使用通道来“共享状态”(如果可以这样调用的话),这样如果我收到 aSender
作为参数,我可以写入它并从进行调用的方法中写入,使用Receiver
to一些东西(例如显示进度条),这就是我正在尝试的:
use tokio::sync::mpsc;
fn upload(file: String, sender: Option<mpsc::Sender<usize>) {
let stream = if let Some(mut tx) = sender {
FramedRead::new(file, BytesCodec::new()).inspect_ok(move |chunk|
tx.send(chunk.len())
)
} else {
FramedRead::new(file, BytesCodec::new())
};
// reqwest
let body = Body::wrap_stream(stream);
client.put(url).body(body)
let body = Body::wrap_stream(stream);
}
我得到的错误是:
`if` and `else` have incompatible types
我也试过:
let stream = FramedRead::new(file, BytesCodec::new());
if let Some(mut tx) = sender {
stream.inspect_ok(move |chunk|
tx.send(chunk.len())
);
}
但是得到mismatched types
这怎么可能实现?有更好的渠道方法吗?
例如,我想使用这样的 crate indicatif:
use tokio::sync::mpsc;
use indicatif::ProgressBar;
use mylibrary::upload;
let (mut tx, mut rx) = mpsc::channel(100);
let bar = ProgressBar::new(1000);
// here pass the sender so that in the receiver i could increment the progress bar
let response = upload("file", Some(tx));
while let Some(i) = rx.recv().await {
bar.inc(1);
}
bar.finish();
解决方案
在 内生成身体if
,以便双臂具有类型Body
:
use tokio::sync::mpsc;
fn upload(file: String, sender: Option<mpsc::Sender<usize>) {
let stream = FramedRead::new(file, BytesCodec::new());
let body = if let Some(mut tx) = sender {
Body::wrap_stream(stream
.inspect_ok(move |chunk| tx.send(chunk.len()))
)
} else {
Body::wrap_stream(stream)
};
// not sure where `client` or `url` are defined?
client.put(url).body(body)
}
或者,根据@SvenMarnach 的建议:
use tokio::sync::mpsc;
use futures::future::Either;
fn upload(file: String, sender: Option<mpsc::Sender<usize>) {
let stream = FramedRead::new(file, BytesCodec::new());
let stream = if let Some(mut tx) = sender {
Either::Left(stream
.inspect_ok(move |chunk| tx.send(chunk.len()))
)
} else {
Either::Right(stream)
};
let body = Body::wrap_stream(stream);
// not sure where `client` or `url` are defined?
client.put(url).body(body)
}
推荐阅读
- swift - 我在哪里从 UIAlertController 的选择中重新加载 tableView?
- python - 在 read_csv() 中忽略的 Pandas 类别 dtypes
- python-3.x - 将多个数据框转换为带有标题的 HTML 页面
- javascript - 在给定条件下修改 JavaScript 中的树结构数据?
- firebase - 如何让登录用户安全连接到数据库?智威汤逊?
- python - 如何在套接字编程python中获取用户PC名称
- xcode - XCODE吊销证书后,Codesign想使用XXX钥匙串
- ibm-integration-bus - 在 IIB 中使用 UDP 中的字段引用
- elasticsearch - 在弹性百分位数内搜索
- css - CSS背景过滤器未在列布局中呈现