diff options
Diffstat (limited to 'libimagruby/README.md')
-rw-r--r-- | libimagruby/README.md | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/libimagruby/README.md b/libimagruby/README.md new file mode 100644 index 00000000..2f761fb1 --- /dev/null +++ b/libimagruby/README.md @@ -0,0 +1,106 @@ +# imag-ruby + +A Ruby gem for scripting imag modules. + +## How does this work? + +Well, as we have some problems with lifetimes here, we have a fairly complex +codebase in this crate. + +### 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()` + +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 +`imag` as a gem which then exports a fine module system. + +### Ideas for module system: + +```text +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. + +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`. + |