Skip to content

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

Merged
tarcieri merged 4 commits into
RustCrypto:masterfrom
tsurdevson:ssh-derive-enum-and-attributes
Apr 19, 2025
Merged

ssh-encoding: add derive feature + extend derive functionallity#348
tarcieri merged 4 commits into
RustCrypto:masterfrom
tsurdevson:ssh-derive-enum-and-attributes

Conversation

@tsurdevson
Copy link
Copy Markdown
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 thread ssh-derive/src/decode.rs
Comment thread ssh-encoding/src/error.rs
Comment on lines +39 to +40
/// Invalid discriminant value in message.
InvalidDiscriminant(u128),
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.

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
Copy Markdown
Member

Going to go ahead and merge this with one nit

@tarcieri tarcieri merged commit d0b974d into RustCrypto:master Apr 19, 2025
@tarcieri tarcieri mentioned this pull request May 25, 2026
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