We store the versions of the packaging tools used by the buildpack (such as pip, setuptools and wheel) in requirements files in the repo, so that Dependabot can update them.
Whilst we can easily include the contents of those files at compile time using include_str!, the buildpack actually needs the version substring rather than the whole requirement specifier (the 1.2.3 from foo==1.2.3).
Until now the extraction/validation of this version substring has been performed at runtime, which required using .expect() to ignore the "technically fallible but never going to fail for users in practice" result.
Now, we use a const fn so this extraction/validation can be performed at compile time, allowing us to define these pinned versions as actual consts. In addition to compile time checks being preferable to those at runtime, this change will allow us to simplify/remove the PackagingToolVersions struct in future PRs in favour of referencing Rust constants.
The features we can use in const fns are limited - we can't use:
most methods on str, including split
iterators (including for loops)
most methods on Option or Result, including expect or unwrap*
We store the versions of the packaging tools used by the buildpack (such as pip, setuptools and wheel) in requirements files in the repo, so that Dependabot can update them.
Whilst we can easily include the contents of those files at compile time using
include_str!
, the buildpack actually needs the version substring rather than the whole requirement specifier (the1.2.3
fromfoo==1.2.3
).Until now the extraction/validation of this version substring has been performed at runtime, which required using
.expect()
to ignore the "technically fallible but never going to fail for users in practice" result.Now, we use a
const fn
so this extraction/validation can be performed at compile time, allowing us to define these pinned versions as actualconst
s. In addition to compile time checks being preferable to those at runtime, this change will allow us to simplify/remove thePackagingToolVersions
struct in future PRs in favour of referencing Rust constants.The features we can use in
const fn
s are limited - we can't use:str
, includingsplit
Option
orResult
, includingexpect
orunwrap*
As such, we convert to bytes and use a while/match pattern to iterate through the string - similar to some of the Rust stdlib
const fn
implementations: https://github.com/rust-lang/rust/blob/6a2cd0d50c9b7e1243d948641758c76d1f22e25e/library/core/src/slice/ascii.rs#L127-L139The minimum Rust version has also been bumped, since
str::trim_ascii
only became aconst fn
in Rust 1.80.GUS-W-16436670.