use std::{default::Default, path::PathBuf};
use strum_macros::{AsRefStr, Display, EnumString};
use std::collections::HashMap;
macro_rules! impl_zfs_prop {
($type_:ty, $as_str:literal) => {
impl ZfsProp for $type_ {
fn nv_key() -> &'static str {
$as_str
}
fn as_nv_value(&self) -> u64 {
*self as u64
}
}
};
}
pub trait ZfsProp {
fn nv_key() -> &'static str;
fn as_nv_value(&self) -> u64;
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum AclInheritMode {
#[strum(serialize = "discard")]
Discard = 0,
#[strum(serialize = "noallow")]
Noallow = 1,
#[strum(serialize = "restricted")]
Restricted = 4,
#[strum(serialize = "secure")]
Secure = 2,
#[strum(serialize = "passthrough")]
Passthrough = 3,
#[strum(serialize = "passthrough-x")]
PassthroughX = 5,
}
impl Default for AclInheritMode {
fn default() -> AclInheritMode {
AclInheritMode::Restricted
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum AclMode {
#[strum(serialize = "discard")]
Discard = 0,
#[strum(serialize = "groupmask")]
GroupMask = 2,
#[strum(serialize = "passthrough")]
Passthrough = 3,
#[strum(serialize = "restricted")]
Restricted = 4,
}
impl Default for AclMode {
fn default() -> AclMode {
AclMode::Discard
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum Checksum {
#[strum(serialize = "inherit")]
Inherit = 0,
#[strum(serialize = "on")]
On = 1,
#[strum(serialize = "off")]
Off = 2,
#[strum(serialize = "noparity")]
NoParity = 10,
#[strum(serialize = "fletcher2")]
Fletcher2 = 6,
#[strum(serialize = "fletcher4")]
Fletcher4 = 7,
#[strum(serialize = "sha256")]
SHA256 = 8,
#[strum(serialize = "sha512")]
SHA512 = 11,
#[strum(serialize = "skein")]
Skein = 12,
}
impl Default for Checksum {
fn default() -> Self {
Checksum::On
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum Compression {
#[strum(serialize = "inherit")]
Inherit = 0,
#[strum(serialize = "on")]
On = 1,
#[strum(serialize = "off")]
Off = 2,
#[strum(serialize = "lzjb")]
LZJB = 3,
#[strum(serialize = "lz4")]
LZ4 = 15,
#[strum(serialize = "zle")]
ZLE = 14,
#[strum(serialize = "gzip-1")]
Gzip1 = 5,
#[strum(serialize = "gzip-2")]
Gzip2 = 6,
#[strum(serialize = "gzip-3")]
Gzip3 = 7,
#[strum(serialize = "gzip-4")]
Gzip4 = 8,
#[strum(serialize = "gzip-5")]
Gzip5 = 9,
#[strum(serialize = "gzip-6")]
Gzip6 = 10,
#[strum(serialize = "gzip-7")]
Gzip7 = 11,
#[strum(serialize = "gzip-8")]
Gzip8 = 12,
#[strum(serialize = "gzip-9")]
Gzip9 = 13,
}
impl Default for Compression {
fn default() -> Self {
Compression::Off
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum Copies {
#[strum(serialize = "1")]
One = 1,
#[strum(serialize = "2")]
Two,
#[strum(serialize = "3")]
Three,
}
impl Default for Copies {
fn default() -> Self {
Copies::One
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum CacheMode {
#[strum(serialize = "all")]
All = 2,
#[strum(serialize = "metadata")]
Metadata = 1,
#[strum(serialize = "none")]
None = 0,
}
impl ZfsProp for CacheMode {
#[allow(clippy::unimplemented)]
fn nv_key() -> &'static str {
unimplemented!()
}
#[allow(clippy::as_conversion)]
fn as_nv_value(&self) -> u64 {
*self as u64
}
}
impl Default for CacheMode {
fn default() -> Self {
CacheMode::All
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum SnapDir {
#[strum(serialize = "hidden")]
Hidden = 0,
#[strum(serialize = "visible")]
Visible = 1,
}
impl Default for SnapDir {
fn default() -> Self {
SnapDir::Hidden
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum CanMount {
#[strum(serialize = "on")]
On = 1,
#[strum(serialize = "off")]
Off = 0,
#[strum(serialize = "noauto")]
NoAuto = 2,
}
impl Default for CanMount {
fn default() -> Self {
CanMount::On
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum SyncMode {
#[strum(serialize = "standard")]
Standard = 0,
#[strum(serialize = "always")]
Always = 1,
#[strum(serialize = "disabled")]
Disabled = 2,
}
impl Default for SyncMode {
fn default() -> Self {
SyncMode::Standard
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum VolumeMode {
#[strum(serialize = "default")]
Default = 0,
#[strum(serialize = "geom")]
GEOM = 1,
#[strum(serialize = "dev")]
Dev = 2,
#[strum(serialize = "none")]
None = 3,
}
impl Default for VolumeMode {
fn default() -> Self {
VolumeMode::Default
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum CaseSensitivity {
#[strum(serialize = "sensitive")]
Sensitive,
#[strum(serialize = "insensitive")]
Insensitive,
#[strum(serialize = "mixed")]
Mixed,
}
impl Default for CaseSensitivity {
fn default() -> Self {
CaseSensitivity::Sensitive
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum Dedup {
#[strum(serialize = "on")]
On,
#[strum(serialize = "off")]
Off,
#[strum(serialize = "verify")]
Verify,
#[strum(serialize = "sha256")]
SHA256,
#[strum(serialize = "sha256,verify")]
VerifySHA256,
#[strum(serialize = "sha512")]
SHA512,
#[strum(serialize = "sha512,verify")]
VerifySHA512,
#[strum(serialize = "skein")]
Skein,
#[strum(serialize = "skein,verify")]
VerifySkein,
}
impl Default for Dedup {
fn default() -> Self {
Dedup::Off
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum Normalization {
#[strum(serialize = "none")]
None,
#[strum(serialize = "formc", serialize = "formC")]
FormC,
#[strum(serialize = "formd", serialize = "formD")]
FormD,
#[strum(serialize = "formkc", serialize = "formKC")]
FormKC,
#[strum(serialize = "formkd", serialize = "formKD")]
FormKD,
}
impl Default for Normalization {
fn default() -> Self {
Normalization::None
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum LogBias {
#[strum(serialize = "latency")]
Latency,
#[strum(serialize = "throughput")]
Throughput,
}
impl Default for LogBias {
fn default() -> Self {
LogBias::Latency
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum RedundantMetadata {
#[strum(serialize = "all")]
All,
#[strum(serialize = "most")]
Most,
}
impl Default for RedundantMetadata {
fn default() -> Self {
RedundantMetadata::All
}
}
#[derive(AsRefStr, EnumString, Display, Eq, PartialEq, Debug, Clone, Copy)]
#[repr(u64)]
pub enum DnodeSize {
#[strum(serialize = "legacy")]
Legacy,
#[strum(serialize = "auto")]
Auto,
#[strum(serialize = "1k")]
_1K,
#[strum(serialize = "2k")]
_2K,
#[strum(serialize = "4k")]
_4K,
#[strum(serialize = "8k")]
_8K,
#[strum(serialize = "16k")]
_16K,
}
impl Default for DnodeSize {
fn default() -> Self {
DnodeSize::Legacy
}
}
#[derive(Debug, Clone, PartialEq, Getters, Builder)]
#[builder(derive(Debug))]
#[get = "pub"]
pub struct FilesystemProperties {
name: PathBuf,
acl_inherit: AclInheritMode,
#[builder(default)]
acl_mode: Option<AclMode>,
atime: bool,
available: i64,
can_mount: CanMount,
case_sensitivity: CaseSensitivity,
checksum: Checksum,
compression: Compression,
compression_ratio: f64,
copies: Copies,
#[builder(default)]
create_txg: Option<u64>,
creation: i64,
#[builder(default)]
dedup: Dedup,
devices: bool,
#[builder(default)]
dnode_size: DnodeSize,
exec: bool,
filesystem_count: Option<u64>,
filesystem_limit: Option<u64>,
#[builder(default)]
guid: Option<u64>,
mounted: bool,
mount_point: Option<PathBuf>,
#[builder(default)]
nbmand: bool,
#[builder(default)]
normalization: Normalization,
primary_cache: CacheMode,
#[builder(default)]
origin: Option<String>,
quota: u64,
readonly: bool,
record_size: u64,
redundant_metadata: RedundantMetadata,
ref_compression_ratio: f64,
referenced: u64,
ref_quota: u64,
ref_reservation: u64,
reservation: u64,
secondary_cache: CacheMode,
setuid: bool,
snap_dir: SnapDir,
snapshot_count: Option<u64>,
snapshot_limit: Option<u64>,
sync: SyncMode,
used: u64,
used_by_children: u64,
used_by_dataset: u64,
used_by_ref_reservation: u64,
used_by_snapshots: u64,
xattr: bool,
#[builder(default)]
jailed: Option<bool>,
log_bias: LogBias,
logical_referenced: u64,
logical_used: u64,
#[builder(default)]
mls_label: Option<String>,
#[builder(default)]
utf8_only: Option<bool>,
version: u64,
written: u64,
volume_mode: Option<VolumeMode>,
#[builder(default)]
vscan: bool,
unknown_properties: HashMap<String, String>,
}
impl FilesystemProperties {
pub fn builder(name: PathBuf) -> FilesystemPropertiesBuilder {
let mut ret = FilesystemPropertiesBuilder::default();
ret.name(name);
ret.unknown_properties(HashMap::new());
ret
}
}
impl FilesystemPropertiesBuilder {
pub fn insert_unknown_property(&mut self, key: String, value: String) {
if let Some(ref mut props) = self.unknown_properties {
props.insert(key, value);
} else {
self.unknown_properties(HashMap::new());
self.insert_unknown_property(key, value);
}
}
}
#[derive(Debug, Clone, PartialEq, Getters, Builder)]
#[get = "pub"]
pub struct VolumeProperties {
name: PathBuf,
available: i64,
checksum: Checksum,
compression: Compression,
compression_ratio: f64,
copies: Copies,
#[builder(default)]
create_txg: Option<u64>,
creation: i64,
#[builder(default)]
dedup: Dedup,
#[builder(default)]
guid: Option<u64>,
log_bias: LogBias,
logical_referenced: u64,
logical_used: u64,
#[builder(default)]
mls_label: Option<String>,
primary_cache: CacheMode,
readonly: bool,
redundant_metadata: RedundantMetadata,
ref_compression_ratio: f64,
referenced: u64,
ref_reservation: u64,
reservation: u64,
secondary_cache: CacheMode,
snapshot_count: Option<u64>,
snapshot_limit: Option<u64>,
sync: SyncMode,
used: u64,
used_by_children: u64,
used_by_dataset: u64,
used_by_ref_reservation: u64,
used_by_snapshots: u64,
volume_block_size: u64,
volume_mode: Option<VolumeMode>,
volume_size: u64,
written: u64,
unknown_properties: HashMap<String, String>,
}
impl VolumeProperties {
pub fn builder(name: PathBuf) -> VolumePropertiesBuilder {
let mut ret = VolumePropertiesBuilder::default();
ret.name(name);
ret.unknown_properties(HashMap::new());
ret
}
}
impl VolumePropertiesBuilder {
pub fn insert_unknown_property(&mut self, key: String, value: String) {
if let Some(ref mut props) = self.unknown_properties {
props.insert(key, value);
} else {
self.unknown_properties(HashMap::new());
self.insert_unknown_property(key, value);
}
}
}
#[derive(Debug, Clone, PartialEq, Getters, Builder)]
#[builder(derive(Debug))]
#[get = "pub"]
pub struct SnapshotProperties {
name: PathBuf,
#[builder(default)]
create_txg: Option<u64>,
creation: i64,
used: u64,
referenced: u64,
compression_ratio: f64,
devices: bool,
exec: bool,
setuid: bool,
xattr: bool,
version: u64,
#[builder(default)]
utf8_only: Option<bool>,
#[builder(default)]
guid: Option<u64>,
primary_cache: CacheMode,
secondary_cache: CacheMode,
defer_destroy: bool,
user_refs: u64,
ref_compression_ratio: f64,
written: u64,
#[builder(default)]
clones: Option<Vec<PathBuf>>,
logically_referenced: u64,
#[builder(default)]
volume_mode: Option<VolumeMode>,
case_sensitivity: CaseSensitivity,
#[builder(default)]
mls_label: Option<String>,
#[builder(default)]
nbmand: bool,
#[builder(default)]
normalization: Normalization,
unknown_properties: HashMap<String, String>,
}
impl SnapshotProperties {
pub fn builder(name: PathBuf) -> SnapshotPropertiesBuilder {
let mut ret = SnapshotPropertiesBuilder::default();
ret.unknown_properties(HashMap::new());
ret.name(name);
ret
}
}
impl SnapshotPropertiesBuilder {
pub fn insert_unknown_property(&mut self, key: String, value: String) {
if let Some(ref mut props) = self.unknown_properties {
props.insert(key, value);
} else {
self.unknown_properties(HashMap::new());
self.insert_unknown_property(key, value);
}
}
}
#[derive(Debug, Clone, PartialEq, Getters, Builder)]
#[builder(derive(Debug))]
#[get = "pub"]
pub struct BookmarkProperties {
name: PathBuf,
#[builder(default)]
create_txg: Option<u64>,
creation: i64,
#[builder(default)]
guid: Option<u64>,
unknown_properties: HashMap<String, String>,
}
impl BookmarkProperties {
pub fn builder(name: PathBuf) -> BookmarkPropertiesBuilder {
let mut ret = BookmarkPropertiesBuilder::default();
ret.unknown_properties(HashMap::new());
ret.name(name);
ret
}
}
impl BookmarkPropertiesBuilder {
pub fn insert_unknown_property(&mut self, key: String, value: String) {
if let Some(ref mut props) = self.unknown_properties {
props.insert(key, value);
} else {
self.unknown_properties(HashMap::new());
self.insert_unknown_property(key, value);
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Properties {
Filesystem(FilesystemProperties),
Volume(VolumeProperties),
Snapshot(SnapshotProperties),
Bookmark(BookmarkProperties),
Unknown(HashMap<String, String>),
}
impl_zfs_prop!(AclInheritMode, "aclinherit");
impl_zfs_prop!(AclMode, "aclmode");
impl_zfs_prop!(CanMount, "canmount");
impl_zfs_prop!(Checksum, "checksum");
impl_zfs_prop!(Compression, "compression");
impl_zfs_prop!(Copies, "copies");
impl_zfs_prop!(SnapDir, "snapdir");
impl_zfs_prop!(VolumeMode, "volmod");