Skip to content

Move hiffy / Idol decoding to a single place#680

Merged
mkeeter merged 2 commits into
masterfrom
mkeeter/consolidate-op-decode
May 28, 2026
Merged

Move hiffy / Idol decoding to a single place#680
mkeeter merged 2 commits into
masterfrom
mkeeter/consolidate-op-decode

Conversation

@mkeeter
Copy link
Copy Markdown
Contributor

@mkeeter mkeeter commented May 26, 2026

Previously, we had two different functions to go from a Result<Vec<u8>, IpcError> to a decoded type: idol_result and hiffy_decode. This PR removes them both in favor of a decode function on IdolOperation:

// Old (two different ways of decoding, somewhat verbose):
hiffy_decode::<u32>(hubris, &op, r)?
context.idol_result::<u32>(&op, &r)?;
// New (one way to decode, shorter):
op.decode::<u32>(&r)?;

The IdolOperation already has a handle to the &HubrisArchive, so we can remove that argument from hiffy_call.

The only significant change is in error design: we now have a strongly-typed IdolDecodeError, which separates "you're holding it wrong" (IdolDecodeError::Failed) from "Idol returned an error" (IdolDecodeError::Idol). The latter is strongly-typed all the way down; the former wraps anyhow::Error in a few places.

Copy link
Copy Markdown
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall, i like this change! i had a few smallish suggestions.

Comment thread humility-idol/src/lib.rs Outdated
Comment on lines +39 to +41
/// Decoding the result failed in Humility
#[error(transparent)]
Failed(#[from] IdolDecodeFailed),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do you feel about naming this something like

Suggested change
/// Decoding the result failed in Humility
#[error(transparent)]
Failed(#[from] IdolDecodeFailed),
/// Decoding the result failed in Humility
#[error(transparent)]
DecodeFailed(#[from] IdolDecodeFailed),

instead? Failed feels a bit unclear to me --- it could just as easily mean "the idol call failed", which is the opposite of what this one means...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable, done!

Comment thread humility-idol/src/lib.rs Outdated
) -> Result<T, IdolDecodeError> {
match val {
Ok(val) => {
let ty = self.hubris.lookup_type(self.ok).unwrap();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, since we are returning errors in all the other "you're holding it wrong" cases, i kind of wonder if we might want to return another error variant here to say "the type you tried to decode the thing to couldn't be found"? maybe not, I dunno.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to just call self.hubris.lookup_type in the constructor and store the value in the IdolOperation, making this a moot point.

Comment thread humility-idol/src/lib.rs Outdated
Comment on lines +306 to +314
::idol::syntax::Encoding::Ssmarshal
| ::idol::syntax::Encoding::Hubpack => {
humility::reflect::deserialize_value(
self.hubris,
val,
ty,
)
.map_err(IdolDecodeFailed::DeserializeValueFailed)?
.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder a bit if we might want to have separate error variants for Ssmarshal and hubpack here so that we can tell you which encoding we were trying to use? or, does the error from humility::reflect::deserialize_value already tell you that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to instead glomp everything in a DeserializeFailed variant, then include the actual Idol encoding.

Comment thread humility-idol/src/lib.rs Outdated
Comment on lines +325 to +350
let out = match err {
IpcError::Error(e) => match self.error {
IdolErrorType::CLike(error) => {
// TODO potentially sign-extended discriminator represented
// as u32 and then zero-extended to u64; won't work for
// signed values. Can't use determine_variant here because
// it's not laid out in memory, it's been unfolded onto the
// return stack.
if let Some(v) =
error.lookup_variant_by_tag(Tag::from(e as u64))
{
IdolError::Named(v.name.to_string())
} else {
IdolError::UnknownErrorVariant(e)
}
}
IdolErrorType::Complex(error) => {
IdolError::ComplexError(error.name.to_string())
}
IdolErrorType::None => {
return IdolDecodeFailed::NoErrorType.into();
}
},
IpcError::ServerDied(c) => IdolError::ServerDied(c),
};
IdolDecodeError::Idol(out)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be honest, i found the use of out here a little hard to follow, i only noticed that after seeing that in the IdleErrorType::None case, there was an explicit return. Part of me wants to say, why don't we just make all the paths that return an IdolErrorexplicitly wrap that inIdolDecodeError::Idol` for clarity, even if it's much uglier-looking? i dunno...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (slightly differently, by just calling .into() everywhere)

Copy link
Copy Markdown
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the view feedback, this looks great!

@mkeeter mkeeter force-pushed the mkeeter/consolidate-op-decode branch from 5ce7f92 to e201e23 Compare May 27, 2026 17:18
Copy link
Copy Markdown
Contributor

@labbott labbott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM I'll let others take a pass before I approve

@mkeeter mkeeter force-pushed the mkeeter/consolidate-op-decode branch from e201e23 to b64cb58 Compare May 27, 2026 19:30
@mkeeter mkeeter force-pushed the mkeeter/consolidate-op-decode branch from b64cb58 to 23b9b85 Compare May 27, 2026 21:01
@mkeeter mkeeter requested a review from Copilot May 27, 2026 21:17
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Consolidates two redundant Idol result-decoding helpers (HiffyContext::idol_result and hiffy_decode) into a single IdolOperation::decode method that leverages the &HubrisArchive already held by IdolOperation. A new strongly-typed IdolDecodeError (with Idol/DecodeFailed variants) and IdolError enum replace the previous String-based error reporting, allowing callers to pattern-match on specific error names rather than comparing stringified messages. The hubris argument is also dropped from hiffy_call and related call sites since it can be obtained via op.

Changes:

  • Introduce IdolOperation::decode plus strongly-typed IdolDecodeError/IdolError/IdolDecodeFailed enums, and rename the lifetime-bearing IdolError<'a> to IdolErrorType<'a>.
  • Remove hiffy_decode and HiffyContext::idol_result, and drop the redundant hubris parameter from hiffy_call.
  • Update all callers (auxflash, hiffy, host, monorail, net, powershelf, qspi, rendmp, sbrmi, tofino-eeprom, validate, vpd, console-proxy) to use the new API, including pattern-matching on IdolError::Named(...) instead of comparing strings.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
humility-idol/src/lib.rs Adds decode/decode_error on IdolOperation, new typed error enums, renames IdolErrorIdolErrorType, caches ok_ty.
humility-idol/Cargo.toml Adds thiserror dependency for new error types.
humility-hiffy/src/lib.rs Removes hiffy_decode/idol_result, drops hubris arg from hiffy_call, changes HiffyError::Hiffy to wrap IdolError, generalizes formatting helpers over any Display error.
humility-auxflash/src/lib.rs Updates hiffy_call call sites and matches on IdolError::Named for "NoActiveSlot"/"MissingChck".
cmd/vpd/src/lib.rs Replaces idol_result calls with op.decode.
cmd/validate/src/lib.rs Updates IdolError::CLikeIdolErrorType::CLike.
cmd/tofino-eeprom/src/lib.rs Drops hubris arg from hiffy_call.
cmd/sbrmi/src/lib.rs Switches to op.decode.
cmd/rendmp/src/lib.rs Removes stored hubris, switches to op.decode, returns IdolError instead of String, matches on new IdolDecodeError variants.
cmd/qspi/src/lib.rs Drops hubris arg from hiffy_call.
cmd/powershelf/src/lib.rs Switches to idol_cmd.decode, matches on IdolDecodeError, passes &result to formatter.
cmd/net/src/lib.rs Updates hiffy_call/hiffy_decode call sites to new API.
cmd/monorail/src/lib.rs Updates calls to new API and matches IdolError::Named for "UnconfiguredPort"/"NoPhy".
cmd/host/src/lib.rs Drops hubris arg from hiffy_call, uses op.decode.
cmd/hiffy/src/lib.rs Updates IdolErrorIdolErrorType matches, drops hubris arg, passes &return_code to hiffy_print_result.
cmd/console-proxy/src/posix.rs Drops hubris arg from hiffy_call.
Cargo.lock Adds thiserror to humility-idol dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread humility-idol/src/lib.rs Outdated
@mkeeter mkeeter force-pushed the mkeeter/consolidate-op-decode branch from 23b9b85 to 5190428 Compare May 27, 2026 21:30
@mkeeter mkeeter merged commit 221e5f1 into master May 28, 2026
12 checks passed
@mkeeter mkeeter deleted the mkeeter/consolidate-op-decode branch May 28, 2026 12:34
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

Successfully merging this pull request may close these issues.

4 participants