Using Rust inside a Crystal program

Hello,

Perfs are similar.
I use FFI to be able to use some crates in Crystal, it allows to use Rust’s echo-system.

If it helps, here’s a little POC in bulk.

├── Cargo.lock
├── Cargo.toml
├── Makefile
├── shard.yml
├── spec
│   ├── myapp_spec.cr
│   └── spec_helper.cr
├── src
│   ├── lib.rs
│   └── myapp.cr

Makefile

ifeq ($(shell uname),Darwin)
    EXT := dylib
else
    EXT := so
endif

all: target/debug/myrust.$(EXT)
	LIBRARY_PATH=$(PWD)/target/debug:$(LIBRARY_PATH) crystal build src/myapp.cr -o myrust
	LD_LIBRARY_PATH=./target/debug ./myrust

target/debug/myrust.$(EXT): src/lib.rs Cargo.toml
	cargo build
	cd src

clean:
	rm -rf target myrust myrust.dwarf

Cargo.tml

[package]
name = "crystal-rust"
version = "0.1.0"

[lib]
name = "myrust"
crate-type = ["dylib"]

shard.yml

name: myapp
version: 0.1.0

authors:
  - Nicolas Talle

targets:
  myapp:
    main: src/myapp.cr

crystal: 0.32.1

license: MIT

lib.rs

#[no_mangle]
pub extern "C" fn string() -> *const u8 {
  "Hello World\0".as_bytes().as_ptr()
}

myapp.cr

@[Link("myrust")]
lib R
  fun string() : UInt8*
end

module Myapp
  VERSION = "0.1.0"

  msg = String.new(R.string())
  puts "from Rust #{msg}"
end

And to compile:

make

I use FFI (Rust) with the v0.34, but I have tested this POC only with Crystal v0.32.

To go further, callbacks help well. Pay attention to who has the ownership of the variables.