use crate::data_types::PoolString;
use crate::mem::PoolAllocation;
use crate::proto::device_path::{DevicePath, DevicePathNode};
use crate::proto::unsafe_protocol;
use crate::{CStr16, Result, Status};
use core::ptr::NonNull;
use uefi_raw::protocol::device_path::{DevicePathFromTextProtocol, DevicePathToTextProtocol};
use super::{PoolDevicePath, PoolDevicePathNode};
#[derive(Clone, Copy, Debug)]
pub struct DisplayOnly(pub bool);
#[derive(Clone, Copy, Debug)]
pub struct AllowShortcuts(pub bool);
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(DevicePathToTextProtocol::GUID)]
pub struct DevicePathToText(DevicePathToTextProtocol);
impl DevicePathToText {
pub fn convert_device_node_to_text(
&self,
device_node: &DevicePathNode,
display_only: DisplayOnly,
allow_shortcuts: AllowShortcuts,
) -> Result<PoolString> {
let text = unsafe {
(self.0.convert_device_node_to_text)(
device_node.as_ffi_ptr().cast(),
display_only.0.into(),
allow_shortcuts.0.into(),
)
};
unsafe { PoolString::new(text.cast()) }
}
pub fn convert_device_path_to_text(
&self,
device_path: &DevicePath,
display_only: DisplayOnly,
allow_shortcuts: AllowShortcuts,
) -> Result<PoolString> {
let text = unsafe {
(self.0.convert_device_path_to_text)(
device_path.as_ffi_ptr().cast(),
display_only.0.into(),
allow_shortcuts.0.into(),
)
};
unsafe { PoolString::new(text.cast()) }
}
}
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol("05c99a21-c70f-4ad2-8a5f-35df3343f51e")]
pub struct DevicePathFromText(DevicePathFromTextProtocol);
impl DevicePathFromText {
pub fn convert_text_to_device_node(
&self,
text_device_node: &CStr16,
) -> Result<PoolDevicePathNode> {
unsafe {
let ptr = (self.0.convert_text_to_device_node)(text_device_node.as_ptr().cast());
NonNull::new(ptr.cast_mut())
.map(|p| PoolDevicePathNode(PoolAllocation::new(p.cast())))
.ok_or_else(|| Status::OUT_OF_RESOURCES.into())
}
}
pub fn convert_text_to_device_path(&self, text_device_path: &CStr16) -> Result<PoolDevicePath> {
unsafe {
let ptr = (self.0.convert_text_to_device_path)(text_device_path.as_ptr().cast());
NonNull::new(ptr.cast_mut())
.map(|p| PoolDevicePath(PoolAllocation::new(p.cast())))
.ok_or_else(|| Status::OUT_OF_RESOURCES.into())
}
}
}