use core::fmt;
#[cfg(feature = "std")]
use crate::events::DocumentEvent;
use super::command::{ExtensionCommand, ExtensionState};
use super::extension::{EditorExtension, MessageHandler};
#[cfg(feature = "std")]
use std::collections::HashMap;
#[cfg(not(feature = "std"))]
use alloc::collections::BTreeMap as HashMap;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, string::String, vec::Vec};
#[cfg(feature = "multi-thread")]
use std::sync::Arc;
#[cfg(not(feature = "multi-thread"))]
use core::cell::RefCell;
#[cfg(feature = "multi-thread")]
use parking_lot::Mutex;
#[cfg(feature = "std")]
use std::sync::mpsc::Sender;
#[cfg(feature = "std")]
pub type EventSender = Sender<DocumentEvent>;
#[cfg(not(feature = "std"))]
pub type EventSender = ();
pub(super) struct ExtensionManagerInner {
pub(super) extensions: HashMap<String, Box<dyn EditorExtension>>,
pub(super) extension_states: HashMap<String, ExtensionState>,
pub(super) commands: HashMap<String, (String, ExtensionCommand)>,
pub(super) config: HashMap<String, String>,
pub(super) extension_data: HashMap<String, HashMap<String, String>>,
#[cfg(feature = "std")]
#[allow(dead_code)]
pub(super) event_tx: EventSender,
#[allow(dead_code)]
pub(super) message_handler: Box<dyn MessageHandler>,
}
pub struct ExtensionManager {
#[cfg(feature = "multi-thread")]
pub(super) inner: Arc<Mutex<ExtensionManagerInner>>,
#[cfg(not(feature = "multi-thread"))]
pub(super) inner: RefCell<ExtensionManagerInner>,
}
#[cfg(feature = "multi-thread")]
impl Clone for ExtensionManager {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl fmt::Debug for ExtensionManager {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[cfg(feature = "multi-thread")]
{
let inner = self.inner.lock();
f.debug_struct("ExtensionManager")
.field("extension_states", &inner.extension_states)
.field("commands", &inner.commands.keys().collect::<Vec<_>>())
.field("config", &inner.config)
.field("extension_data", &inner.extension_data)
.field("extensions", &"<HashMap<String, Box<dyn EditorExtension>>>")
.finish()
}
#[cfg(not(feature = "multi-thread"))]
{
let inner = self.inner.borrow();
f.debug_struct("ExtensionManager")
.field("extension_states", &inner.extension_states)
.field("commands", &inner.commands.keys().collect::<Vec<_>>())
.field("config", &inner.config)
.field("extension_data", &inner.extension_data)
.field("extensions", &"<HashMap<String, Box<dyn EditorExtension>>>")
.finish()
}
}
}
impl ExtensionManager {
#[cfg(feature = "multi-thread")]
pub(super) fn with_inner_mut<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut ExtensionManagerInner) -> R,
{
let mut inner = self.inner.lock();
f(&mut inner)
}
#[cfg(feature = "multi-thread")]
pub(super) fn with_inner<F, R>(&self, f: F) -> R
where
F: FnOnce(&ExtensionManagerInner) -> R,
{
let inner = self.inner.lock();
f(&inner)
}
#[cfg(not(feature = "multi-thread"))]
pub(super) fn with_inner_mut<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut ExtensionManagerInner) -> R,
{
let mut inner = self.inner.borrow_mut();
f(&mut inner)
}
#[cfg(not(feature = "multi-thread"))]
pub(super) fn with_inner<F, R>(&self, f: F) -> R
where
F: FnOnce(&ExtensionManagerInner) -> R,
{
let inner = self.inner.borrow();
f(&inner)
}
}
impl Default for ExtensionManager {
fn default() -> Self {
Self::new()
}
}