feat(types)!: Unknown(String) fallback on every response enum - #119
Open
extremeandy wants to merge 8 commits into
Open
extremeandy wants to merge 8 commits into
extremeandy wants to merge 8 commits into
Conversation
extremeandy
commented
Sep 3, 2026
extremeandy
commented
Sep 3, 2026
extremeandy
commented
Sep 3, 2026
extremeandy
commented
Sep 3, 2026
extremeandy
commented
Sep 3, 2026
extremeandy
commented
Sep 3, 2026
extremeandy
commented
Sep 3, 2026
2 tasks
extremeandy
added a commit
that referenced
this pull request
Sep 3, 2026
Replace the `String` fields on `BorrowLendMarket::state` and `BorrowLendMarketHistoryParams::interval` with enums, following the pattern from #119. - `BorrowLendBookState` is a response-side enum whose set can grow, so it uses serde_with's `SerializeDisplay` / `DeserializeFromStr` over strum and carries a `#[strum(default)] Unknown(String)` fallback with the raw wire value. - `BorrowLendMarketHistoryInterval` is request-only with a fixed set (`1d`, `1w`, `1month`, `1year`), so it stays closed and `Copy`, like `VaultHistoryInterval`. Wire values verified against bpx-backend `api/types/src/borrow_lend.rs`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
5 tasks
karunmatharu
pushed a commit
that referenced
this pull request
Sep 14, 2026
* feat: add borrow/lend market endpoints Expose public borrow/lend market APIs (markets, history, APY rates) with types, client methods, example, and integration tests. * feat(types): typed enums for borrow/lend book state and history interval Replace the `String` fields on `BorrowLendMarket::state` and `BorrowLendMarketHistoryParams::interval` with enums, following the pattern from #119. - `BorrowLendBookState` is a response-side enum whose set can grow, so it uses serde_with's `SerializeDisplay` / `DeserializeFromStr` over strum and carries a `#[strum(default)] Unknown(String)` fallback with the raw wire value. - `BorrowLendMarketHistoryInterval` is request-only with a fixed set (`1d`, `1w`, `1month`, `1year`), so it stays closed and `Copy`, like `VaultHistoryInterval`. Wire values verified against bpx-backend `api/types/src/borrow_lend.rs`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ponse enums Response-side enums that were closed now parse any value the exchange sends: a recognised string maps to its variant, anything else lands in a new `Unknown(String)` variant carrying the raw wire value. Serde delegates to the strum `Display` / `FromStr` impls through a small `serde_via_strum!` macro, so each enum's wire strings live in one place. Converted: TriggerBy, TimeInForce, SelfTradePrevention, OrderStatus, SystemOrderType, Side, OrderUpdateType, RfqExecutionMode, VaultRedeemStatus. BREAKING CHANGE: these enums are now `#[non_exhaustive]` (downstream `match` needs a wildcard arm) and no longer implement `Copy` (the fallback carries a `String`). `Clone` is kept. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Blockchain, DepositSource, DepositStatus, WithdrawalStatus, OrderBookState and RwaMarketType already fell back to a unit `Unknown` variant on unrecognised values. They now use the same strum-backed `Unknown(String)` shape as the rest of the response enums, so callers can log the value the exchange sent. BREAKING CHANGE: `Unknown` on these enums now carries a `String` (match with `Unknown(_)`), the enums are `#[non_exhaustive]`, and `Copy` is dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nge emits OrderStatus gains `TriggerFailed` (emitted today) and `PendingRelease`; OrderUpdateType gains `SpeedbumpPlaced` and `SpeedbumpFailed` (wire values `speedbumpPlaced` / `speedbumpFailed`), which arrive with the firm taker speedbump. Message-level tests cover each, plus an unknown event and status landing in `Unknown` with the raw value. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Bring Blockchain, DepositSource, DepositStatus and WithdrawalStatus up to the set the exchange reports. DepositSource now lists every chain plus the payment processors and internal transfers; its multi-word names carry explicit wire strings (`hyperEVM`, `xRP`, `0G`) because the API only lowercases the first character. `DepositSource::Nuvei` and `WithdrawalStatus::Verifying` never appear on the wire and are deprecated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
RequestForQuoteUpdate is internally tagged on `e` with struct payloads, so it cannot use the strum-backed fallback. It gains a unit `#[serde(other)] Unknown` variant and is `#[non_exhaustive]`, so an event type this client does not know parses instead of failing the stream. The raw tag is not preserved for this one enum. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t finds CI ran clippy without `--all-targets`, so integration tests were never linted and `just check` disagreed with CI. Align the two and drop the needless borrow in `get_historical_fills.rs` that the wider run flags. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Use serde_with's `SerializeDisplay` / `DeserializeFromStr` derives instead of a hand-rolled macro. - Keep `Side`, `TimeInForce` and `SelfTradePrevention` closed and `Copy`: the engine's sets are fixed. Revert the example clone that came with it. - Delete `DepositSource::Nuvei` and `WithdrawalStatus::Verifying` rather than deprecating them; neither appears on the wire. - Defer `PendingRelease`, `SpeedbumpPlaced` and `SpeedbumpFailed` to a stacked PR gated on the backend speedbump change. `TriggerFailed` stays: it is emitted today. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
extremeandy
force-pushed
the
claude/unknown-string-enum-fallback-1e103a
branch
from
September 14, 2026 01:51
e45c5bc to
f5d723a
Compare
bpx-backend master added both payment processors since the audit this branch was built against. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Response-side enums whose value set can grow now parse any value the exchange sends. A recognised string maps to its variant; anything else lands in a new
Unknown(String)variant carrying the raw wire value, so callers can log what they got instead of failing the whole response.Motivation:
OrderStatuslacksTriggerFailed, which the engine emits today, so any order row or WebSocket order update carrying it fails to deserialize in 0.21.0.What changed
SerializeDisplay/DeserializeFromStrderives delegate serde to the strumDisplay/FromStrimpls, so each enum's wire strings live in one place. Every open enum has a#[strum(default)] Unknown(String)variant.OrderStatus,OrderUpdateType,SystemOrderType,RfqExecutionMode,VaultRedeemStatus,TriggerBy.UnknowntoUnknown(String):Blockchain,DepositSource,DepositStatus,WithdrawalStatus,OrderBookState,RwaMarketType.Copybecause the engine's sets are fixed:Side,TimeInForce,SelfTradePrevention.OrderStatus::TriggerFailed, six blockchains, the full deposit source list, and the deposit/withdrawal statuses the API reports.DepositSource::NuveiandWithdrawalStatus::Verifyingnever appear on the wire and are removed.RequestForQuoteUpdateis internally tagged with struct payloads, so it gets a unit#[serde(other)] Unknowninstead. The rawetag is not preserved for this one enum.FillType,SortDirection,OrderBookDepthLimit,VaultHistoryInterval,SlippageToleranceType) are untouched.--all-targets, matchingjust check, and the one warning that surfaced is fixed.Breaking changes
Copyis removed from every converted enum (aStringpayload cannot beCopy).Cloneis kept.Unknownon the six enums that already had it now carries aString: match withUnknown(_).#[non_exhaustive]: downstreammatchneeds a wildcard arm.DepositSource::NuveiandWithdrawalStatus::Verifyingare removed.The only Backpack consumer is bpx-cli, pinned to 0.20. Its exhaustive matches are on
TimeInForceandSide, which stay closed, so it should upgrade cleanly.Notes
DepositSource::HyperEVMandDepositSource::XRPcarry explicithyperEVM/xRPoverrides. Tests pin the exact strings. Verified against bpx-backend at61e5f9a7b8.minorafter merge.Test plan
just check(fmt, clippy all targets/features)just test: per-enum round-trip tests, unknown-value fallback tests, whole-message tests fortriggerFailedand an unknown order event, status and RFQ event.🤖 Generated with Claude Code