feat: port npm lockfile to Rust (#3632)
Adds a Rust port of the npm lockfile implementation only used when
`GO_TAG=rust` is set.
Notes:
- The crawling of the lockfile graph is done in the language of the
lockfile impl to avoid incurring ffi overhead for every transitive
dependency. This change requires moving this function into the lockfile
package instead of context in Go (this is probably where it should've
belonged all along)
- We explicitly make an ffi function in Rust for each lockfile
implementation. This adds boilerplate, but as this boundary should be
short lived (only around until package graph gets moved into Rust) this
is acceptable instead of coming up with a more generic solution.
- If we stick with passing the lockfile contents for other
implementations then we will be able to share the protobuf message
definitions
---------
Co-authored-by: Alexander Lyon <arlyon@me.com>