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

read_into : Richer return types from item-reading functions #10

Open
ZackPierce opened this issue Feb 7, 2020 · 0 comments
Open

read_into : Richer return types from item-reading functions #10

ZackPierce opened this issue Feb 7, 2020 · 0 comments

Comments

@ZackPierce
Copy link
Contributor

Right now when you want to read content from a single member of a struct in an array, you provide a function that works with the starting "ready to read" state for that struct and return a Result containing the "done reading" state for that struct.

Concretely, the signature for the primary read method of an "item in an array" state-struct is:

        pub fn read<F>(self, f: F) -> Result<(), rust_lcm_codec::DecodeValueError<R::Error>>
        where
            F: FnOnce(
                member_read_ready<'a, R>,
            ) -> Result<member_read_done<'a, R>, rust_lcm_codec::DecodeValueError<R::Error>>;

In practice, this means that the outer read function doesn't return anything useful to the end-user, so any state mutation must by be reference to something captured by closure (e.g. writing to a mutable field on the stack). This makes the side effects of reading less visible. Furthermore , the only errors that can be piped are LCM-specific errors.

I am currently proposing a slightly more expanded option where the handler function can actually return some content and error-types of interest to the end user.

pub fn read_into<F, T, CustomDecodeError>(self, f: F) -> Result<T, rust_lcm_codec::DecodeValueError<R::Error, CustomDecodeError>>
        where
            F: FnOnce(
                member_read_ready<'a, R>,
            ) -> Result<(member_read_done<'a, R>, T), rust_lcm_codec::DecodeValueError<R::Error, CustomDecodeError>>;

In the end, I would rather have:

let outcome = item_reader.read_into(|ready| {
   // do stuff with `ready`, including some possibly-fallible operations
  let (v, r) = ready.read_thing()?;
  let outcome = possibly_fallible_interpretation(v).map_err(|e| DecodeValueError::Custom(e))?;
  let (_, done) = r.read_some_other_thing()?;
  Ok((done, outcome))
})?;

than what I have to do now,

let mut maybe_outcome_result = None;
item_reader.read(|ready| {
   // do stuff with `ready`, including some possibly-fallible operations
  let (v, r) = ready.read_thing()?;
  maybe_outcome_result = Some(possibly_fallible_interpretation(v));
  let (_, done) = r.read_some_other_thing()?;
  Ok(done)
})?;
if let Some(result) = maybe_outcome_result {
    let outcome = result?;
}

This will require modifying DecodeValueError to have an addition Custom variant accepting a user-selected type.

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

1 participant