Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RequestResponseError が複雑なので良い感じにしたい #4

Open
tomoyuki-nakabayashi opened this issue May 21, 2021 · 6 comments

Comments

@tomoyuki-nakabayashi
Copy link
Collaborator

WouldBlock を共通化するなら、nb::Result どこかで導入できると、
下あたりが

loop {
let result = Response::receive_response(
&mut transport,
&mut frame_buffer,
BasicCodecFactory::new(),
);
match result {
Ok((response, mut codec)) => {
println!(
"Ok. response = {}, {}, {}, {}",
response.service,
response.request,
response.sequence,
response.is_notification
);
if let Ok(result) = codec.read_u32() {
println!("\tresult = {}", result);
} else {
println!("\tno result...");
}
break;
}
Err(err) => {
if let RequestResponseError::FramedTransportError(
FramedTransportError::UnderlyingError(underlying_error),
) = &err
{
if underlying_error.kind() == std::io::ErrorKind::WouldBlock {
continue;
}
} else {
}
println!("Error: {:?}", err);
continue 'main;
}
}
}

こうできないかなぁ、みたいな?

    let result = nb::block!(Response::receive_response(...)?;
    // Ok の場合の処理を書く
@tomoyuki-nakabayashi
Copy link
Collaborator Author

下から全部合成していくのは厳しいから、crate 用の Error 型定義して、Into は実装ごとに書いてね、って感じが良いかな。

@tomoyuki-nakabayashi
Copy link
Collaborator Author

thiserror の no_std 対応はまだマージされてないのか… (だいぶ前も見た気がする) 。

dtolnay/thiserror#64

@ciniml
Copy link
Owner

ciniml commented May 23, 2021

そうすると現状の no_std だと何使うんが良さそうだろうか。 (エラー周りはやり方統一されてないっぽいから自前で適当に書いてた)

@tomoyuki-nakabayashi
Copy link
Collaborator Author

今みたいに自前で合成していくので良いと思います。
thiserror 使えるようになるとちょっと楽できる、くらいで。

ただ、どこかで切れ目作って、今作っているやつを上位から使う時に楽にできると良いかなぁ、と (それが WouldBlock あたりの話ですね) 。

カジュアルに nb::Result を階層化して使えると良いのですけど、ぱっとやり方がわからなくて、調査中です…。
UnderlyingTransportnb::Error::WouldBlock になると、FramedTransport に自動的に WouldBlock が伝播できると良さそうなんですけど…。

@tomoyuki-nakabayashi
Copy link
Collaborator Author

nb::Error<E> -> nb::Error<F> は map が提供されているので、nb::Result<T, E> に対して、次のような感じで一般化できる。

    result.map_err(|e| e.map(|e| FramedError::TransportError(e)))

io::Error -> nb::Error は愚直に書くしかなさそう (Into / From 使った一般化は難しそう) 。

    result.map_err(|e| match e {
            io::Error::WouldBlock => nb::Error::WouldBlock,
            _ => e.into(), // io::Error -> nb::Error<T> への Into
        })

というのも、任意のエラーを表現する enum E に対して、nb::Error<E> への Into が実装されているので、特殊化で無理矢理解決したいところだけど、そうもいかない。

@tomoyuki-nakabayashi
Copy link
Collaborator Author

@ciniml
一旦こんな感じで PR 書いてみようと思いますが、send も nb にする…?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants