virtualization_rs/virtualization/
storage_device.rs

1//! storage device module
2
3use crate::base::{Id, NSError, NSURL};
4
5use objc::runtime::BOOL;
6use objc::{class, msg_send, sel, sel_impl};
7use objc::{rc::StrongPtr, runtime::NO, runtime::YES};
8
9/// common configure of storage device attachment
10pub trait VZStorageDeviceAttachment {
11    fn id(&self) -> Id;
12}
13
14/// builder for VZDiskImageStorageDeviceAttachment
15/// # Examples
16/// ```rust
17/// let block_attachment = match VZDiskImageStorageDeviceAttachmentBuilder::new()
18///     .path(canonicalize(&disk).unwrap().into_os_string().into_string().unwrap())
19///     .build()
20/// {
21///     Ok(x) => x,
22///     Err(err) => {
23///         err.dump();
24///         return;
25///     }
26/// };
27/// ```
28pub struct VZDiskImageStorageDeviceAttachmentBuilder<Path, ReadOnly> {
29    path: Path,
30    read_only: ReadOnly,
31}
32
33impl VZDiskImageStorageDeviceAttachmentBuilder<(), bool> {
34    pub fn new() -> Self {
35        VZDiskImageStorageDeviceAttachmentBuilder {
36            path: (),
37            read_only: true,
38        }
39    }
40}
41
42impl<Path, ReadOnly> VZDiskImageStorageDeviceAttachmentBuilder<Path, ReadOnly> {
43    pub fn path<T: Into<String>>(
44        self,
45        path: T,
46    ) -> VZDiskImageStorageDeviceAttachmentBuilder<String, ReadOnly> {
47        VZDiskImageStorageDeviceAttachmentBuilder {
48            path: path.into(),
49            read_only: self.read_only,
50        }
51    }
52
53    pub fn read_only(
54        self,
55        read_only: bool,
56    ) -> VZDiskImageStorageDeviceAttachmentBuilder<Path, bool> {
57        VZDiskImageStorageDeviceAttachmentBuilder {
58            path: self.path,
59            read_only: read_only,
60        }
61    }
62}
63
64impl VZDiskImageStorageDeviceAttachmentBuilder<String, bool> {
65    pub fn build(self) -> Result<VZDiskImageStorageDeviceAttachment, NSError> {
66        let read_only = if self.read_only { YES } else { NO };
67        unsafe { VZDiskImageStorageDeviceAttachment::new(self.path.as_str(), read_only) }
68    }
69}
70
71/// configure of disk image storage device attachment
72pub struct VZDiskImageStorageDeviceAttachment(StrongPtr);
73
74impl VZDiskImageStorageDeviceAttachment {
75    unsafe fn new(
76        path: &str,
77        read_only: BOOL,
78    ) -> Result<VZDiskImageStorageDeviceAttachment, NSError> {
79        let i: Id = msg_send![class!(VZDiskImageStorageDeviceAttachment), alloc];
80        let path_nsurl = NSURL::file_url_with_path(path, false);
81        let error = NSError::nil();
82        let p = StrongPtr::new(
83            msg_send![i, initWithURL:*path_nsurl.0 readOnly:read_only error:&(*error.0)],
84        );
85        if error.code() != 0 {
86            Err(error)
87        } else {
88            Ok(VZDiskImageStorageDeviceAttachment(p))
89        }
90    }
91}
92
93impl VZStorageDeviceAttachment for VZDiskImageStorageDeviceAttachment {
94    fn id(&self) -> Id {
95        *self.0
96    }
97}
98
99/// configure of storage device
100pub trait VZStorageDeviceConfiguration {
101    fn id(&self) -> Id;
102}
103
104/// configure of storage device through the Virtio interface
105pub struct VZVirtioBlockDeviceConfiguration(StrongPtr);
106
107impl VZVirtioBlockDeviceConfiguration {
108    pub fn new<T: VZStorageDeviceAttachment>(attachment: T) -> VZVirtioBlockDeviceConfiguration {
109        unsafe {
110            let i: Id = msg_send![class!(VZVirtioBlockDeviceConfiguration), alloc];
111            let p = StrongPtr::new(msg_send![i, initWithAttachment:attachment.id()]);
112            VZVirtioBlockDeviceConfiguration(p)
113        }
114    }
115}
116
117impl VZStorageDeviceConfiguration for VZVirtioBlockDeviceConfiguration {
118    fn id(&self) -> Id {
119        *self.0
120    }
121}