diff --git a/libimagruby/README.md b/libimagruby/README.md index 92939c35..2f761fb1 100644 --- a/libimagruby/README.md +++ b/libimagruby/README.md @@ -2,35 +2,105 @@ A Ruby gem for scripting imag modules. -This crate contains both the Rust bindings for imag using `ruru` and a bunch of -wrapper code for the actual `imag` gem. +## How does this work? -## Why another layer of indirection? +Well, as we have some problems with lifetimes here, we have a fairly complex +codebase in this crate. -As "ruru" does not yet support modules, which is sad btw, we would end up with +### The Problem + +The Problem is, that `libimagstore::store::FileLockEntry<'a>` has a lifetime. If +we would wrap this object into a ruru wrapper and pass to the Ruby code, we +couldn't guarantee anymore that the lifetime holds. + +The problem is simple, you see... + +### The solution? + +Never pass anything to the Ruby code. + +Yes, exactly. The Ruby code only sees 'handles'. It never actually gets the +`Store` object either. +We move the `Store` Object into a `Cache` object (actually, the Ruby code could +have multiple `Store` objects to work with this way) and return a `StoreHandle` +to the Ruby code (which is a UUID underneath). + +Also, the Ruby code never actually touches a `FileLockEntry` - it only gets a +Handle for each `FileLockEntry` - which is a tuple of the `StoreHandle` and the +`libimagstore::storeid::StoreId` for the Entry. + +Each operation on a `FileLockEntry` is then wrapped by this very library. Each +time `FileLockEntry` is touched, this library fetches the appropriate `Store` +object from the static `Cache`, then fetches the `FileLockEntry` object from it, +does the operation and then drops the object (which implies that the actual +`FileLockEntry` is `update()`d!). + +### The Hell? + +Yes, I know this is a lot of overhead. But what are we talking about here? This +is Ruby code we're talking about here, so speed is not our concern. + +You could argue this is a hell of complexity introduced in this library and yes +it is. +If there are bugs (and I bet there are) they would be complex as hell. +But that's it... if you have a better approach, please file a PR. + +## Tests? + +We have tests Ruby scripts in `./test`, they are not executed by travis-ci, as +we need Ruby `2.3.0` for this and travis has `2.2.0` as latest version. +But I hope we get it in travis soonish. + +## Ruby gem? + +This crate will contain both the Rust bindings for imag using `ruru` and a bunch +of wrapper code for the actual `imag` gem. + +We are not there yet, though. + +### Why another layer of indirection? + +As "ruru" does not yet support modules (which is sad btw) we would end up with functions for all the things. -E.G.: `imag_runtime_setup()` instead of `IMAG::Runtime::setup()` +E.G.: `imag_runtime_setup()` instead of `Imag::Runtime::setup()` I want to add a Ruby gem to wrap these things. -So basically a piece of ruby which uses `imag.rb` (the Rust gem) to build + +So basically a piece of Ruby which uses `imag.rb` (the Rust gem) to build `imag` as a gem which then exports a fine module system. -## Ideas for module system: +### Ideas for module system: ```text -IMAG (Module) - Runtime (Module) - Runtime (Class) - Store (Module) - Store (Class) - Entry (Class) - StoreId (Class) - Util (Module, Ruby-only I guess) +Imag (Module) + Runtime (Class) + Store (Class) + Entry (Class) + EntryHeader (Class) + EntryContent (Class (inherits from String)) + StoreId (Class) ``` I would name the types the same as in the Rust codebase, to avoid confusion. Only exception would be the `Entry` class, which would be a `FileLockEntry` -underneath and if we adapt `libimagentrytag` and the other `libimagentry*` +underneath. + +If we adapt `libimagentrytag` and the other `libimagentry*` libraries, we would extend this type. +## More plans + +I want to pull these libraries into the Ruby bindings: + +* libimagentryedit +* libimagentryfilter +* libimagentrylink +* libimagentrylist +* libimagentrymarkdown +* libimagentrytag +* libimagentryview + +Which all provide functions on top of `libimagstore::store::{FileLock,}Entry`, +so we will implement them on `Imag::Entry`. +