aboutsummaryrefslogtreecommitdiffstats
path: root/zone_core/src/container.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2022-05-06 14:27:17 -0500
committerToby Vincent <tobyv13@gmail.com>2022-05-06 14:27:17 -0500
commitcdb45e032b078156eddbd47cb350c6ae66a64098 (patch)
tree796dc0597c410d23053e72e0af9d23a6cb26313e /zone_core/src/container.rs
parent730305eb1a6f9615dccb9bd94b1c371bba003615 (diff)
refactor: generalize zfs impl into storage traits
Diffstat (limited to 'zone_core/src/container.rs')
-rw-r--r--zone_core/src/container.rs125
1 files changed, 62 insertions, 63 deletions
diff --git a/zone_core/src/container.rs b/zone_core/src/container.rs
index 71dfb73..db7458e 100644
--- a/zone_core/src/container.rs
+++ b/zone_core/src/container.rs
@@ -1,57 +1,92 @@
use clap::Args;
-use derive_builder::Builder;
use serde::{Deserialize, Serialize};
-use std::{fmt::Display, path::PathBuf};
+use std::{ffi::OsStr, fmt::Display, path::PathBuf};
use tabled::Tabled;
use crate::FilterContainer;
-pub use status::ContainerStatus;
+pub use self::error::ParsingError;
+pub use self::status::Status;
+mod error;
mod status;
-#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Builder, Tabled, Clone, Args)]
-#[builder(
- name = "ContainerOptions",
- derive(Debug, Serialize, Deserialize),
- field(public)
-)]
+#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Tabled, Clone, Args)]
#[serde(rename_all = "camelCase")]
pub struct Container {
#[tabled("ID")]
- pub id: u64,
+ pub id: u32,
#[tabled("Template")]
- pub parent: String,
+ pub template: String,
#[tabled("User")]
- pub user: String,
-}
-
-impl Container {
- pub fn builder() -> ContainerOptions {
- ContainerOptions::default()
- }
+ pub owner: String,
}
impl Display for Container {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}-{}-{}", self.user, self.parent, self.id)
+ write!(f, "{}-{}-{}", self.template, self.owner, self.id)
}
}
impl From<Container> for String {
fn from(c: Container) -> Self {
- format!("{}-{}-{}", c.user, c.parent, c.id)
+ format!("{}-{}-{}", c.template, c.owner, c.id)
}
}
+impl From<Container> for PathBuf {
+ fn from(c: Container) -> Self {
+ PathBuf::from(format!("{}/{}/{}", c.template, c.owner, c.id))
+ }
+}
+
+impl TryFrom<String> for Container {
+ type Error = ParsingError;
+
+ fn try_from(s: String) -> Result<Self, Self::Error> {
+ let v = s.split('-').collect::<Vec<_>>();
+ match v[v.len() - 3..] {
+ [i, o, t] => Ok(Container {
+ id: i.parse()?,
+ owner: o.into(),
+ template: t.into(),
+ }),
+ _ => Err(s).map_err(ParsingError::from),
+ }
+ }
+}
+
+impl TryFrom<PathBuf> for Container {
+ type Error = ParsingError;
+
+ fn try_from(p: PathBuf) -> Result<Self, Self::Error> {
+ let v = p.iter().map(OsStr::to_str).collect::<Vec<_>>();
+ match v[v.len() - 3..] {
+ [Some(i), Some(o), Some(t)] => Ok(Container {
+ id: i.parse()?,
+ owner: o.into(),
+ template: t.into(),
+ }),
+ _ => Err(p).map_err(ParsingError::from),
+ }
+ }
+}
+
+#[derive(Debug, Default, Serialize, Deserialize)]
+pub struct ContainerOptions {
+ pub id: Option<u32>,
+ pub parent: Option<String>,
+ pub owner: Option<String>,
+}
+
impl From<Container> for ContainerOptions {
fn from(c: Container) -> Self {
Self {
id: Some(c.id),
- parent: Some(c.parent),
- user: Some(c.user),
+ parent: Some(c.template),
+ owner: Some(c.owner),
}
}
}
@@ -60,8 +95,8 @@ impl From<&Container> for &ContainerOptions {
fn from(c: &Container) -> Self {
ContainerOptions {
id: Some(c.id.to_owned()),
- parent: Some(c.parent.to_owned()),
- user: Some(c.user.to_owned()),
+ parent: Some(c.template.to_owned()),
+ owner: Some(c.owner.to_owned()),
}
.into()
}
@@ -76,7 +111,7 @@ impl From<ContainerOptions> for &ContainerOptions {
#[derive(Debug, Serialize, Deserialize, Clone, Args)]
pub struct CloneOptions {
pub template: String,
- pub user: String,
+ pub owner: String,
}
impl<T> FilterContainer for T
@@ -88,45 +123,9 @@ where
self.filter_map(|c| -> Option<Container> { c.try_into().ok() })
.filter(|c| {
pred.id.map_or(false, |p| p == c.id)
- && pred.parent.as_ref().map_or(false, |p| p == &c.parent)
- && pred.user.as_ref().map_or(false, |p| p == &c.user)
+ && pred.parent.as_ref().map_or(false, |p| p == &c.template)
+ && pred.owner.as_ref().map_or(false, |p| p == &c.owner)
})
.collect()
}
}
-
-impl TryFrom<zone_zfs::FileSystem> for Container {
- type Error = zone_zfs::Error;
-
- fn try_from(fs: zone_zfs::FileSystem) -> zone_zfs::Result<Self> {
- let path_buf = PathBuf::from(fs.dataset())
- .file_name()
- .ok_or_else(|| {
- zone_zfs::Error::FileSystem(format!("Invalid FileSystem path: {:?}", fs))
- })?
- .to_string_lossy()
- .into_owned();
-
- let (user, id) = path_buf.rsplit_once('-').ok_or_else(|| {
- zone_zfs::Error::FileSystem(format!("Invalid FileSystem name: {:?}", fs))
- })?;
-
- let id = id.parse::<u64>().map_err(|err| {
- zone_zfs::Error::FileSystem(format!("Failed to parse container ID: {:?}", err))
- })?;
-
- let template = PathBuf::from(fs.dataset())
- .parent()
- .ok_or_else(|| {
- zone_zfs::Error::FileSystem(format!("Invalid path for filesystem: {:?}", &fs))
- })?
- .to_string_lossy()
- .into_owned();
-
- Ok(Container {
- id,
- parent: template,
- user: user.to_string(),
- })
- }
-}