Files
Bugen Zhao 39910f2b25 [Rust Frontend] Move code from vllm-frontend-rs (#43283)
Signed-off-by: Bugen Zhao <i@bugenzhao.com>
Signed-off-by: Nick Hill <nickhill123@gmail.com>
Signed-off-by: Eric Curtin <eric.curtin@docker.com>
Signed-off-by: Dev-X25874 <283057883+Dev-X25874@users.noreply.github.com>
Signed-off-by: Will.hou <1205157517@qq.com>
Signed-off-by: Will.hou <willamhou@ceresman.com>
Co-authored-by: Nick Hill <nickhill123@gmail.com>
Co-authored-by: Eric Curtin <eric.curtin@docker.com>
Co-authored-by: Dev-X25874 <283057883+Dev-X25874@users.noreply.github.com>
Co-authored-by: Will.hou <1205157517@qq.com>
Co-authored-by: Will.hou <willamhou@ceresman.com>

Please see https://github.com/Inferact/vllm-frontend-rs for full original commit history.
2026-05-21 17:21:48 -07:00

4.0 KiB

Alternative Frontend to vLLM Engine in Rust

This project aims to implement an alternative frontend to the vLLM Engine in Rust, providing a more efficient and robust interface for interacting with the engine. Currently it's still in the very early stage and is actively evolving.

Coding Styles

  • Always use workspace dependencies for Cargo crates.
  • Prefer splitting code into multiple smaller modules and files for better organization and readability, rather than putting everything in a single file.
  • When refactoring or reconstructing code, always preserve the original comments and documentation VERBATIM, if applicable.
  • If not specified, default to writing concise Rust documentation and comments that match the style of the existing codebase when generating code.
  • When migrating code from Python or any other language, preserve the original documentation comments whenever they still make sense in the Rust code.
  • Although you might be asked to only implement or migrate minimal functionality at the beginning, you should still leave necessary TODO comments in the code for the future improvements of the lacked features, so that it's easier for the next iteration to build upon the existing codebase.
  • When writing parsers with winnow:
    • Prefer a declarative parser shape over imperative step-by-step parsing, as long as it's more readable and maintainable.
    • Prefer tuple-based parser composition over calling parse_next one parser at a time.
    • Prefer built-in combinators and token parsers before adding local helpers.
    • Add short documentation comments like Parse a .. to all local parser/combinator functions.
    • Reuse existing utilities from utils module as much as possible, and add new ones there if needed.
  • Rust error handling:
    • Never call to_string() directly on an error value.
    • Use ToReportString or AsReport by thiserror-ext instead.
    • For Error variants that are primarily free-form text, prefer a struct variant with a message: String field. thiserror_ext::Macro will auto-derive foo!(...) and bail_foo!(...) helper macros from that shape.
      • Use foo!(...) when you need to construct an error value inside an expression, such as Err(foo!(...)), .ok_or_else(|| foo!(...)), or Err::<(), _>(foo!(...))?.
      • Use bail_foo!(...) only in statement positions where you want to exit the current Result-returning function immediately. Prefer it over return Err(foo!(...)) in those cases.
      • If a variant has extra structured fields, prefer the generated macro form foo!(field = value, "message") rather than manually writing Error::Foo { ... }.
  • Since the project is still in early stage, it's fine to break API and make non-backwards-compatible changes as needed.
  • Currently the project is only targeting Unix-like platforms, so it's fine to use Unix-specific APIs without extra compatibility layers like cfg(unix)

Testing

  • Prefer snapshot testing with the expect-test crate over writing multiple assert_eq! statements on individual fields. Use expect_test::expect![[...]].assert_debug_eq(...) to snapshot the Debug output of the entire struct.
    • Write expect![[""]] as a placeholder first, then run UPDATE_EXPECT=1 cargo test to auto-fill the snapshot content.
    • For values containing non-deterministic data (e.g., UUIDs), set them to a fixed value like "<placeholder>" before snapshotting.
  • In tests, avoid hand-writing full request struct literals when only a few fields matter. Prefer test fixtures such as for_test() with struct update syntax, so newly added fields do not force mechanical edits across many tests.
  • Prefer deterministic synchronization in async and integration tests, such as channels, barriers, explicit handshakes, or observable state transitions, instead of sleep-based timing assumptions.
    • Use sleep only as a last resort when there is no better observable synchronization point.
  • Always run test with cargo nextest run instead of cargo test, if available, as it's much faster.