use crate::HasDirectPropertyGroups;
use crate::PropertyGroup;
use crate::PropertyGroupDirect;
use crate::PropertyGroupType;
use crate::Scf;
use crate::error::LibscfError;
use crate::error::PropertyGroupAddError;
use crate::error::PropertyGroupDeleteError;
use crate::error::ToEntityDescription;
use crate::scf::ScfObject;
use crate::utf8cstring::Utf8CString;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[non_exhaustive] pub enum AddPropertyGroupFlags {
Persistent,
NonPersistent,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum DeletePropertyGroupResult {
Deleted,
DoesNotExist,
}
pub trait EditPropertyGroups:
HasDirectPropertyGroups + ToEntityDescription
{
fn add_property_group(
&mut self,
name: &str,
pg_type: PropertyGroupType,
flags: AddPropertyGroupFlags,
) -> Result<PropertyGroup<'_, PropertyGroupDirect>, PropertyGroupAddError>;
fn ensure_property_group(
&mut self,
name: &str,
pg_type: PropertyGroupType,
flags: AddPropertyGroupFlags,
) -> Result<PropertyGroup<'_, PropertyGroupDirect>, PropertyGroupAddError>
{
match self.add_property_group(name, pg_type, flags) {
Ok(_)
| Err(PropertyGroupAddError::Add {
err: LibscfError::Exists,
..
}) => (),
Err(err) => return Err(err),
}
match self.property_group_direct(name) {
Ok(Some(property_group)) => Ok(property_group),
Ok(None) => Err(PropertyGroupAddError::DeletedDuringEnsure {
parent: self.to_entity_description(),
name: Box::from(name),
}),
Err(err) => Err(PropertyGroupAddError::ExistenceLookup {
parent: self.to_entity_description(),
name: Box::from(name),
err,
}),
}
}
fn delete_property_group(
&mut self,
name: &str,
) -> Result<DeletePropertyGroupResult, PropertyGroupDeleteError> {
let pg = match self.property_group_direct(name) {
Ok(Some(pg)) => pg,
Ok(None) => return Ok(DeletePropertyGroupResult::DoesNotExist),
Err(err) => {
return Err(PropertyGroupDeleteError::Lookup {
parent: self.to_entity_description(),
name: name.to_string().into_boxed_str(),
err,
});
}
};
pg.delete()
}
}
pub(crate) struct AddPropertyGroupArgs<'a> {
pub(crate) name: Utf8CString,
pub(crate) handle: ScfObject<'a, libscf_sys::scf_propertygroup_t>,
pub(crate) flags: u32,
}
impl<'a> AddPropertyGroupArgs<'a> {
pub(crate) fn validate<P: ToEntityDescription>(
scf: &'a Scf<'_>,
parent: &P,
name: &str,
flags: AddPropertyGroupFlags,
) -> Result<Self, PropertyGroupAddError> {
let name = Utf8CString::from_str(name).map_err(|err| {
PropertyGroupAddError::InvalidName {
parent: parent.to_entity_description(),
name: Box::from(name),
err,
}
})?;
let handle = scf.scf_pg_create()?;
let flags = match flags {
AddPropertyGroupFlags::Persistent => 0,
AddPropertyGroupFlags::NonPersistent => {
libscf_sys::SCF_PG_FLAG_NONPERSISTENT
}
};
Ok(Self { name, handle, flags })
}
}