use core::fmt;
use lean_rs::error::LeanResult;
use lean_rs::module::{LeanBuiltCapability, LeanCapability, LeanLibrary};
use crate::host::cancellation::LeanCancellationToken;
use crate::host::host::LeanHost;
use crate::host::progress::LeanProgressSink;
use crate::host::session::LeanSession;
use crate::host::shim_bindings::host_shim_export_signatures;
pub struct LeanCapabilities<'lean, 'h> {
host: &'h LeanHost<'lean>,
_user_library: Option<LeanLibrary<'lean>>,
shim_capability: LeanCapability<'lean>,
}
impl fmt::Debug for LeanCapabilities<'_, '_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("LeanCapabilities").finish_non_exhaustive()
}
}
impl<'lean, 'h> LeanCapabilities<'lean, 'h> {
pub(crate) fn new(
host: &'h LeanHost<'lean>,
user_library: LeanLibrary<'lean>,
package: &str,
lib_name: &str,
) -> LeanResult<Self> {
let shim_capability = load_shim_capability(host)?;
let _user_module = user_library.initialize_module(package, lib_name)?;
Ok(Self {
host,
_user_library: Some(user_library),
shim_capability,
})
}
pub(crate) fn new_shims_only(host: &'h LeanHost<'lean>) -> LeanResult<Self> {
let shim_capability = load_shim_capability(host)?;
Ok(Self {
host,
_user_library: None,
shim_capability,
})
}
pub fn session<'c>(
&'c self,
imports: &[&str],
cancellation: Option<&LeanCancellationToken>,
progress: Option<&dyn LeanProgressSink>,
) -> LeanResult<LeanSession<'lean, 'c>> {
LeanSession::import(self, imports, cancellation, progress)
}
pub(crate) fn host(&self) -> &'h LeanHost<'lean> {
self.host
}
pub(crate) fn shim_capability(&self) -> &LeanCapability<'lean> {
&self.shim_capability
}
}
fn load_shim_capability<'lean>(host: &LeanHost<'lean>) -> LeanResult<LeanCapability<'lean>> {
let built = crate::host::lake::LakeProject::shim_capability(host_shim_export_signatures())?;
LeanCapability::from_build_manifest(
host.runtime(),
LeanBuiltCapability::manifest_path(built.manifest_path()),
)
}