I'm a relative Rust noob, coming from a Python background. Really enjoying the learning experience so far - and in particular the top-notch documentation and community!
I'm up against a situation that I'm not sure how to approach. So far I've implemented a simple key-value store with SQLite as a backend. My current implementation is in the playground here. It creates an instance of the Db
struct that includes a connection an in-memory SQLite database, inserts an Cat
object (serialized as JSON), and reads it back out. So far so good.
Currently he Db
struct has the public methods open()
, get()
, and set()
.
Now, I'd like to split my implementation in two different types of database access:
- One would be
DbRW
, which incorporates all of the above functionality. - The other would be
DbRO
, which only allows read-only functionality (soopen()
, andget()
)
(FWIW, the reason I want this is that in reality this would be used with an on-disk database that's accessed by multiple processes, and I'd like to be explicit about the type of access that each process would have)
Obviously I don't want to have separate implementations of DbRO
and DbRW
which essentially duplicate the open()
and get()
methods. [In principle the open()
method would actually differ slightly, since the DbRO
version would open the database itself in read-only mode]
Where I'm stuck is that I'm not sure how to approach this from a trait/struct perspective. I've read pieces like Implementing an Object-Oriented Design Pattern - The Rust Programming Language and Traits - Rust By Example but I'm not sure how to apply them in this case.
My best guess was to have DbRW
and DbRO
be structs, with a common Db
trait that contains the common logic and returns the right type of struct on open()
- but attempting to implement that quickly throws up "object safety" issues that I'm not sure how to address.
error[E0038]: the trait `Db` cannot be made into an object
Would appreciate any pointers on how to achieve something like the above in Rust?