Replies: 2 comments 2 replies
-
|
Further minimized: use snafu::prelude::*;
use std::convert::TryFrom;
#[derive(Debug, Snafu)]
pub enum ColorError {
UnknownColor { input: String },
}
pub type Result<T, E = ColorError> = std::result::Result<T, E>;
#[derive(Debug, Clone, Copy)]
pub struct Color;
impl TryFrom<&str> for Color {
type Error = ColorError;
fn try_from(_: &str) -> Result<Self> {
Ok(Color)
}
}
fn takes_a_try(input: impl TryInto<Color>) -> Result<()> {
let color: Color = input.try_into()?;
Ok(())
}
fn main() -> Result<()> {
Ok(())
}
This is not guaranteed. For example, one could add impl TryFrom<bool> for Color {
type Error = String;
fn try_from(_: bool) -> Result<Self, Self::Error> {
Ok(Color)
}
}Your argument requires that something is convertible to a fn takes_a_try(input: impl TryInto<Color, Error = ColorError>) -> Result<()> {Note that nothing here is SNAFU-specific. |
Beta Was this translation helpful? Give feedback.
-
Fair enough. Thanks for the pointers. I did think it might be Snafu specific in that their are extra structs being created and the derive macros even can be used to specific different scopes and I expected the solution to come from that quarter.
But I didn't. I could add a lot of things that would break this, but I kind of expected the compiler to error based on the code I asked it to compile, not some theoretical other code I could add later. (Yes I'm still a little confused on this point.)
Aah yes. I should have mentioned I actually found that as a potential work around when I was coming up with this MWE. Unfortunately I also discarded it as impractical since specifying the error type for input traits makes the function much less flexible than I need it to be. Armed with your redirection back to that point, I hacked on it some more and I think I came up with something that actually covers my use case, which includes functioning for for infalliable types. It does involve a bit of shenanigans casting #!/usr/bin/env rust-script
//! ```cargo
//! [dependencies]
//! snafu = "0.8"
//! ```
use snafu::prelude::*;
use std::convert::TryFrom;
#[derive(Debug, Snafu)]
pub enum ColorError {
UnknownColor {},
}
impl From<std::convert::Infallible> for ColorError {
fn from(_: std::convert::Infallible) -> Self {
unreachable!("If you got here, the universe is inside out.")
}
}
pub type Result<T, E = ColorError> = std::result::Result<T, E>;
pub struct Color;
impl TryFrom<&str> for Color {
type Error = ColorError;
fn try_from(_: &str) -> Result<Self> {
Ok(Self)
}
}
fn takes_a_try<T>(input: T) -> Result<()>
where
T: TryInto<Color>,
ColorError: From<T::Error>,
{
let _: Color = input.try_into()?;
Ok(())
}
fn main() {
let _ = takes_a_try("");
let _ = takes_a_try(Color);
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I have a fairly convoluted crate that gets used is several different contexts (compiled to WASM, into a Lua module, into a Python module, etc.). I'm trying to refactor it a bit to avoid panics that can cross those boundaries ... because duh! However the resulting error handling using Snafu is giving me conniptions. The actual code in context is here, but I've gotten as far as distilling it down to a similar set of scopes and trait implementations in MWE that can be run with
rust-scriptfrom a single file:The result I get throws these errors:
For the life of me I can't figure out why the
?operator is having trouble converting error types given that everything here is already the same error type. I was unable to replicate this error without the extra layers of complexity caused by having the error types and other things in a different module scope than the functions running them.I did figure out ways to work around this, mostly by using
.map_err()to flatten the error and re-create it, but its a mess and I'd like to clean it up and keep it simple. Why isn't this error type propagating?Beta Was this translation helpful? Give feedback.
All reactions