User plugin foundations for 0.6.0 (#257)

Starts work on #55.

This is similar to the previous work in #125. It's gated behind a new Cargo
feature, `user-plugins`. This time, the config gate is much smaller. The
`plugins` member of projects is still accessible when plugins aren't enabled,
but is always empty. Additionally, user plugins are only enabled if there's a
Lua state present in the snapshot context when the `SnapshotUserPlugins`
snapshot middleware runs. This not ever the case currently.

This code has very little possibility of rotting while we focus on other work,
since it'll be guaranteed to still compile and can be tested in isolation
without the feature being turned on.
This commit is contained in:
Lucien Greathouse 2019-10-11 15:45:02 -07:00 • committed by GitHub
parent f3dc78b7cd
commit b093626a21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 306 additions and 22 deletions

View file

@ -1,8 +1,12 @@
use std::{fmt, ops::Deref, path::PathBuf};
use rlua::{Lua, RegistryKey};
#[derive(Debug)]
pub struct InstanceSnapshotContext {
/// Empty struct that will be used later to fill out required Lua state for
/// user plugins.
pub plugin_context: Option<()>,
pub plugin_context: Option<SnapshotPluginContext>,
}
impl Default for InstanceSnapshotContext {
@ -13,4 +17,47 @@ impl Default for InstanceSnapshotContext {
}
}
#[derive(Debug)]
pub struct SnapshotPluginContext {
pub state: IgnoreDebug<Lua>,
/// Paths to the user plugins files. These paths are generated by the root
/// project file, if there is one.
pub plugin_paths: Vec<PathBuf>,
/// Lazy-initialized registry keys pointing to the values returned by each
/// user plugin. When processing user plugins, these should be applied in
/// order.
pub plugin_functions: Option<Vec<RegistryKey>>,
}
impl SnapshotPluginContext {
pub fn new(plugin_paths: Vec<PathBuf>) -> Self {
Self {
state: IgnoreDebug(Lua::new()),
plugin_paths,
plugin_functions: None,
}
}
}
/// Utility type to enable having a field of a struct not implement Debug and
/// instead show a placeholder.
#[derive(Clone)]
pub struct IgnoreDebug<T>(pub T);
impl<T> fmt::Debug for IgnoreDebug<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "<no debug representation>")
}
}
impl<T> Deref for IgnoreDebug<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
pub struct ImfsSnapshotContext;