Pointers shared across function bounds in Rustler?

At the risk of forking another thread to discuss the same problem, I’m including my progress from today. There seems to have been a bunch of discussion on this before!

In my case, I’m bouncing between two different errors as I decide if I need to impl Resource or if I need to make a new type that mimics GraphDb with the necessary trait (seems likely).

base code:

use rustler::ResourceArc;
use rustler::Resource;
use rustler::{Env};

use sparrowdb::GraphDb;

rustler::atoms! { ok, error }
rustler::init!("Elixir.Spare", [open]);

enum Response {
  Success(ResourceArc<sparrowdb::GraphDb>),
  Failure(String),
}

// #[rustler::nif(schedule = "DirtyCPU")]
// #[rustler::nif(schedule = "DirtyIo")]
#[rustler::nif]
fn open(base: &str) -> Response {
  match GraphDb::open(std::path::Path::new(base)) {
      Ok(graph) => Response.Success(ResourceArc::new(graph)),
      Error(e) => Response.Failure(e.to_string())
  }
}

I may be soooooo off here, this is a hodgepodge from combining examples.


error[E0277]: the trait bound `GraphDb: Resource` is not satisfied
  --> native/spare/src/lib.rs:20:54
   |
20 |       Ok(graph) => Response.Success(ResourceArc::new(graph)),
   |                                     ---------------- ^^^^^ the trait `Resource` is not implemented for `GraphDb`
   |                                     |
   |                                     required by a bound introduced by this call
   |
note: required by a bound in `ResourceArc::<T>::new`
  --> /home/calliope/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustler-0.38.0/src/resource/arc.rs:39:8
   |
39 |     T: Resource,
   |        ^^^^^^^^ required by this bound in `ResourceArc::<T>::new`
...
43 |     pub fn new(data: T) -> Self {
   |            --- required by a bound in this associated function

error[E0277]: the trait bound `GraphDb: Resource` is not satisfied
  --> native/spare/src/lib.rs:20:37
   |
20 |       Ok(graph) => Response.Success(ResourceArc::new(graph)),
   |                                     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Resource` is not implemented for `GraphDb`
   |
note: required by a bound in `ResourceArc`
  --> /home/calliope/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustler-0.38.0/src/resource/arc.rs:27:8
   |
25 | pub struct ResourceArc<T>
   |            ----------- required by a bound in this struct
26 | where
27 |     T: Resource,
   |        ^^^^^^^^ required by this bound in `ResourceArc`


Then, if I include this impl Resource, the error changes:

#[rustler::resource_impl]
impl Resource for sparrowdb::GraphDb
{
  fn destructor(self, env: Env<'_>) {
    drop(self)
  }
}
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> native/spare/src/lib.rs:26:1
   |
26 | impl Resource for sparrowdb::GraphDb
   | ^^^^^^^^^^^^^^^^^^------------------
   |                   |
   |                   `GraphDb` is not defined in the current crate
   |
   = note: impl doesn't have any local type before any uncovered type parameters
   = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
   = note: define and implement a trait or new type instead