use {
crate::{
control::ControlParagraph,
dependency::{DependencyList, PackageDependencyFields},
error::{DebianError, Result},
io::ContentDigest,
package_version::PackageVersion,
repository::{builder::DebPackageReference, release::ChecksumType},
},
std::ops::{Deref, DerefMut},
};
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct BinaryPackageControlFile<'a> {
paragraph: ControlParagraph<'a>,
}
impl<'a> Deref for BinaryPackageControlFile<'a> {
type Target = ControlParagraph<'a>;
fn deref(&self) -> &Self::Target {
&self.paragraph
}
}
impl<'a> DerefMut for BinaryPackageControlFile<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.paragraph
}
}
impl<'a> From<ControlParagraph<'a>> for BinaryPackageControlFile<'a> {
fn from(paragraph: ControlParagraph<'a>) -> Self {
Self { paragraph }
}
}
impl<'a> From<BinaryPackageControlFile<'a>> for ControlParagraph<'a> {
fn from(cf: BinaryPackageControlFile<'a>) -> Self {
cf.paragraph
}
}
impl<'a> BinaryPackageControlFile<'a> {
pub fn package(&self) -> Result<&str> {
self.required_field_str("Package")
}
pub fn version_str(&self) -> Result<&str> {
self.required_field_str("Version")
}
pub fn version(&self) -> Result<PackageVersion> {
PackageVersion::parse(self.version_str()?)
}
pub fn architecture(&self) -> Result<&str> {
self.required_field_str("Architecture")
}
pub fn maintainer(&self) -> Result<&str> {
self.required_field_str("Maintainer")
}
pub fn description(&self) -> Result<&str> {
self.required_field_str("Description")
}
pub fn source(&self) -> Option<&str> {
self.field_str("Source")
}
pub fn section(&self) -> Option<&str> {
self.field_str("Section")
}
pub fn priority(&self) -> Option<&str> {
self.field_str("Priority")
}
pub fn essential(&self) -> Option<&str> {
self.field_str("Essential")
}
pub fn homepage(&self) -> Option<&str> {
self.field_str("Homepage")
}
pub fn installed_size(&self) -> Option<Result<u64>> {
self.field_u64("Installed-Size")
}
pub fn size(&self) -> Option<Result<u64>> {
self.field_u64("Size")
}
pub fn built_using(&self) -> Option<&str> {
self.field_str("Built-Using")
}
pub fn depends(&self) -> Option<Result<DependencyList>> {
self.field_dependency_list("Depends")
}
pub fn recommends(&self) -> Option<Result<DependencyList>> {
self.field_dependency_list("Recommends")
}
pub fn suggests(&self) -> Option<Result<DependencyList>> {
self.field_dependency_list("Suggests")
}
pub fn enhances(&self) -> Option<Result<DependencyList>> {
self.field_dependency_list("Enhances")
}
pub fn pre_depends(&self) -> Option<Result<DependencyList>> {
self.field_dependency_list("Pre-Depends")
}
pub fn package_dependency_fields(&self) -> Result<PackageDependencyFields> {
PackageDependencyFields::from_paragraph(self)
}
}
impl<'cf, 'a: 'cf> DebPackageReference<'cf> for BinaryPackageControlFile<'a> {
fn deb_size_bytes(&self) -> Result<u64> {
self.size()
.ok_or_else(|| DebianError::ControlRequiredFieldMissing("Size".to_string()))?
}
fn deb_digest(&self, checksum: ChecksumType) -> Result<ContentDigest> {
let hex_digest = self
.paragraph
.field_str(checksum.field_name())
.ok_or_else(|| {
DebianError::ControlRequiredFieldMissing(checksum.field_name().to_string())
})?;
ContentDigest::from_hex_digest(checksum, hex_digest)
}
fn deb_filename(&self) -> Result<String> {
let filename = self
.field_str("Filename")
.ok_or_else(|| DebianError::ControlRequiredFieldMissing("Filename".to_string()))?;
Ok(if let Some((_, s)) = filename.rsplit_once('/') {
s.to_string()
} else {
filename.to_string()
})
}
fn control_file_for_packages_index(&self) -> Result<BinaryPackageControlFile<'cf>> {
Ok(self.clone())
}
}