use crate::core::Result;
use super::command::ExtensionState;
use super::context::ExtensionContext;
use super::extension::EditorExtension;
use super::manager::ExtensionManager;
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, string::ToString};
impl ExtensionManager {
pub fn load_extension(&mut self, extension: Box<dyn EditorExtension>) -> Result<()> {
let extension_name = extension.info().name.clone();
let dependencies = extension.info().dependencies.clone();
let has_deps = self.with_inner(|inner| {
dependencies
.iter()
.all(|dep| inner.extension_states.contains_key(dep))
});
if !has_deps {
return Err(crate::core::EditorError::CommandFailed {
message: format!("Extension '{extension_name}' has unmet dependencies"),
});
}
self.with_inner_mut(|inner| {
if inner.extensions.contains_key(&extension_name) {
return Err(crate::core::EditorError::CommandFailed {
message: format!("Extension '{extension_name}' is already loaded"),
});
}
inner.extensions.insert(extension_name.clone(), extension);
inner
.extension_states
.insert(extension_name.clone(), ExtensionState::Uninitialized);
Ok(())
})
}
pub fn initialize_extension(
&mut self,
extension_name: &str,
context: &mut dyn ExtensionContext,
) -> Result<()> {
self.with_inner_mut(|inner| {
inner
.extension_states
.insert(extension_name.to_string(), ExtensionState::Initializing);
if let Some(extension) = inner.extensions.get_mut(extension_name) {
match extension.initialize(context) {
Ok(()) => {
inner
.extension_states
.insert(extension_name.to_string(), ExtensionState::Active);
for command in extension.commands() {
inner
.commands
.insert(command.id.clone(), (extension_name.to_string(), command));
}
Ok(())
}
Err(e) => {
inner
.extension_states
.insert(extension_name.to_string(), ExtensionState::Error);
Err(e)
}
}
} else {
Err(crate::core::EditorError::CommandFailed {
message: format!("Extension '{extension_name}' not found"),
})
}
})
}
pub fn unload_extension(
&mut self,
extension_name: &str,
context: &mut dyn ExtensionContext,
) -> Result<()> {
self.shutdown_extension(extension_name, context)?;
self.with_inner_mut(|inner| {
inner.extensions.remove(extension_name);
inner.extension_states.remove(extension_name);
inner
.commands
.retain(|_, (ext_name, _)| ext_name != extension_name);
inner.extension_data.remove(extension_name);
});
Ok(())
}
fn shutdown_extension(
&mut self,
extension_name: &str,
context: &mut dyn ExtensionContext,
) -> Result<()> {
self.with_inner_mut(|inner| {
inner
.extension_states
.insert(extension_name.to_string(), ExtensionState::ShuttingDown);
if let Some(extension) = inner.extensions.get_mut(extension_name) {
extension.shutdown(context)?;
inner
.extension_states
.insert(extension_name.to_string(), ExtensionState::Shutdown);
}
Ok(())
})
}
}