use crate::pdcstring::PdCStr;
use crate::{
bindings::{consts::MAX_PATH, nethost::get_hostfxr_parameters},
error::Error,
hostfxr::{HostExitCode, Hostfxr},
};
use std::{ffi::OsString, mem::MaybeUninit, ptr};
pub fn get_hostfxr_path() -> Result<OsString, Error> {
unsafe { get_hostfxr_path_with_parameters(ptr::null()) }
}
pub fn get_hostfxr_path_with_assembly_path<P: AsRef<PdCStr>>(
assembly_path: P,
) -> Result<OsString, Error> {
let parameters = get_hostfxr_parameters::with_assembly_path(assembly_path.as_ref().as_ptr());
unsafe { get_hostfxr_path_with_parameters(¶meters) }
}
pub fn get_hostfxr_path_with_dotnet_root<P: AsRef<PdCStr>>(
dotnet_root: P,
) -> Result<OsString, Error> {
let parameters = get_hostfxr_parameters::with_dotnet_root(dotnet_root.as_ref().as_ptr());
unsafe { get_hostfxr_path_with_parameters(¶meters) }
}
unsafe fn get_hostfxr_path_with_parameters(
parameters: *const get_hostfxr_parameters,
) -> Result<OsString, Error> {
let mut path_buffer = MaybeUninit::uninit_array::<MAX_PATH>();
let mut path_length = path_buffer.len();
let result = unsafe {
crate::bindings::nethost::get_hostfxr_path(
path_buffer.as_mut_ptr().cast(),
&mut path_length,
parameters,
)
};
HostExitCode::from(result).to_result()?;
let path_slice = unsafe { MaybeUninit::slice_assume_init_ref(&path_buffer[..path_length]) };
Ok(unsafe { PdCStr::from_slice_with_nul_unchecked(path_slice) }.to_os_string())
}
pub fn load_hostfxr() -> Result<Hostfxr, Error> {
let hostfxr_path = get_hostfxr_path()?;
Hostfxr::load_from_path(hostfxr_path)
}
pub fn load_hostfxr_with_assembly_path<P: AsRef<PdCStr>>(
assembly_path: P,
) -> Result<Hostfxr, Error> {
let hostfxr_path = get_hostfxr_path_with_assembly_path(assembly_path)?;
Hostfxr::load_from_path(hostfxr_path)
}
pub fn load_hostfxr_with_dotnet_root<P: AsRef<PdCStr>>(dotnet_root: P) -> Result<Hostfxr, Error> {
let hostfxr_path = get_hostfxr_path_with_dotnet_root(dotnet_root)?;
Hostfxr::load_from_path(hostfxr_path)
}