Skip to content

ssh-encoding: add derive feature + extend derive functionallity #348

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

Merged
merged 4 commits into from
Apr 19, 2025

Conversation

tsurdevson
Copy link
Contributor

I wanted to be able to derive Encode and Decode for various message types in RFC 4253 and related RFCs. As the current implementation has some limitations (and I wanted to get some more macro-writing practice), I've gone ahead and extended ssh-derive quite a bit. The result is a rather substantial refactor, but it now supports all types of structs as well as enums. I realize this might be a bit much to review, but seeing as ssh-derive is 0.0.1-alpha I figured it might be alright.

This PR is really in two parts (let me know if it is better merged as two separate things):

  • ssh-derive:
    • Allow deriving Encode/Decode on all kinds of structs and enums.
    • Introduce derive attributes to control the generated impls.
      • #[ssh(length_prefixed)] to use length prefixing when encoding/decoding. Can be applies to the struct/enum itself, or to individual fields.
      • #[repr(u8)] and friends: Enum discriminants will encode/decode with the type specified by the repr attribute.
  • ssh-encoding:
    • Add a derive feature that re-exports the derive macros from ssh-derive.
    • Add a new error variant to ssh_encoding::Error to handle unexpected discriminant values when decoding.
    • Add tests and documentation for the derive feature.

Extend the derive macros to support all struct and enum types, not just
simple structs.

This also introduces some custom attributes to control the derived code.
Supported attributes:

  - `#[ssh(length_prefixed)]`: will use length-prefix encoding/decoding
    for the struct/enum as a whole, or per field, depending on where the
    attribute is placed.
  - `#[repr(u8)]`, `#[repr(u32)]` etc.: Enum discriminants will be
    encoded/decoded depending on the specified repr used.
This is used in derived `Decode` implementations for enums. It holds a
u128 because discriminants may be as large as u128/i128. Storing the
value isn't strictly necessary, but allows a better error message.
Adds an optional feature that re-exports `ssh-derive` macros and exposes
a documentation module with examples. The examples also serve as tests.

Also adds tests for the derive feature in the form of declaring various
structs and enums and asserting that encoding/decoding works as expected.
@tsurdevson tsurdevson force-pushed the ssh-derive-enum-and-attributes branch from db0b490 to 2583df4 Compare March 30, 2025 13:27
Comment on lines +39 to +40
/// Invalid discriminant value in message.
InvalidDiscriminant(u128),
Copy link
Member

Choose a reason for hiding this comment

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

It seems weird to me to conflate custom derive errors with this error type. Perhaps you could just define an error type in ssh-derive?

@tarcieri
Copy link
Member

Going to go ahead and merge this with one nit

@tarcieri tarcieri merged commit d0b974d into RustCrypto:master Apr 19, 2025
30 checks passed
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.

2 participants