parsely_impl/
error.rs

1use crate::parsely_write::ParselyWrite;
2
3pub type ParselyResult<T> = anyhow::Result<T>;
4
5/// Helper trait to coerce values of both `T: ParselyWrite` and `Result<T, E>: E:
6/// Into<anyhow::Error>` into `ParselyResult<T>`.  We need a trait specifically for writing because
7/// if we don't bound the impl for `T` in some way there's ambiguity: the compiler doesn't know if
8/// we want `ParselyResult<T>` or `ParselyResult<Result<T, E>>`.
9pub trait IntoWritableParselyResult<T> {
10    fn into_parsely_result(self) -> ParselyResult<T>;
11}
12
13impl<T> IntoWritableParselyResult<T> for T
14where
15    T: ParselyWrite,
16{
17    fn into_parsely_result(self) -> ParselyResult<T> {
18        Ok(self)
19    }
20}
21
22impl<T, E> IntoWritableParselyResult<T> for Result<T, E>
23where
24    E: Into<anyhow::Error>,
25{
26    fn into_parsely_result(self) -> ParselyResult<T> {
27        self.map_err(Into::into)
28    }
29}
30
31/// When we need to convert an expression that may or may not be wrapped in a Result on the _read_
32/// path, we can rely on the fact that we'll eventually be assigning the value to a field with a
33/// concrete type and we can rely on type inference in order to figure out what that should be.
34/// Because of that we don't want/need the `ParselyWrite` trait bounds on the impl like we have
35/// above for the writable side, so we need a different trait here.
36pub trait IntoParselyResult<T> {
37    fn into_parsely_result_read(self) -> ParselyResult<T>;
38}
39
40impl<T> IntoParselyResult<T> for T {
41    fn into_parsely_result_read(self) -> ParselyResult<T> {
42        Ok(self)
43    }
44}
45
46impl<T, E> IntoParselyResult<T> for Result<T, E>
47where
48    E: Into<anyhow::Error>,
49{
50    fn into_parsely_result_read(self) -> ParselyResult<T> {
51        self.map_err(Into::into)
52    }
53}