docs(grouping): add docstrings

This commit is contained in:
steven-omaha
2023-05-19 16:05:27 +02:00
parent 85de801e59
commit e74368df7f
3 changed files with 66 additions and 7 deletions
@@ -58,9 +58,19 @@ pub trait Backend: Debug {
fn get_managed_packages(&self) -> &HashSet<Package>; fn get_managed_packages(&self) -> &HashSet<Package>;
/// Get all packages that are installed in the system. /// Get all packages that are installed in the system.
///
/// # Errors
///
/// This function shall return an error if the installed packages cannot be
/// determined.
fn get_all_installed_packages(&self) -> Result<HashSet<Package>>; fn get_all_installed_packages(&self) -> Result<HashSet<Package>>;
/// Get all packages that were installed in the system explicitly. /// Get all packages that were installed in the system explicitly.
///
/// # Errors
///
/// This function shall return an error if the explicitly installed packages
/// cannot be determined.
fn get_explicitly_installed_packages(&self) -> Result<HashSet<Package>>; fn get_explicitly_installed_packages(&self) -> Result<HashSet<Package>>;
/// Assign each of the packages to an individual group by editing the /// Assign each of the packages to an individual group by editing the
@@ -76,7 +86,13 @@ pub trait Backend: Debug {
Ok(()) Ok(())
} }
/// Install the specified packages. /// Install the specified packages. If `noconfirm` is `true`, pass the corresponding
/// switch to the package manager. Return the [`ExitStatus`] from the package manager.
///
/// # Errors
///
/// This function will return an error if the package manager cannot be run or it
/// returns an error.
fn install_packages(&self, packages: &[Package], noconfirm: bool) -> Result<ExitStatus> { fn install_packages(&self, packages: &[Package], noconfirm: bool) -> Result<ExitStatus> {
let mut cmd = Command::new(self.get_binary()); let mut cmd = Command::new(self.get_binary());
cmd.args(self.get_switches_install()); cmd.args(self.get_switches_install());
+32 -1
View File
@@ -23,7 +23,7 @@ pub struct Group {
} }
impl Group { impl Group {
/// Load all group files from the pacdef group dir by recursing through the group dir. /// Load all group files from the pacdef group dir by traversing through the group dir.
/// ///
/// This method will print a warning if /// This method will print a warning if
/// - there are no files under `group_dir`, or /// - there are no files under `group_dir`, or
@@ -105,6 +105,17 @@ impl Eq for Group {
} }
impl Group { impl Group {
/// Load the group from `path`. Determine the name from the path relative to the
/// `group_dir`.
///
/// # Warnings
///
/// This function will print a warning if any section in the group file cannot
/// be processed, or the file contains no sections.
///
/// # Errors
///
/// This function will return an error if the group file cannot be read.
fn try_from<P>(path: P, group_dir: P) -> Result<Self> fn try_from<P>(path: P, group_dir: P) -> Result<Self>
where where
P: AsRef<Path>, P: AsRef<Path>,
@@ -146,6 +157,11 @@ impl Group {
/// Add the new `packages` to the group file under the section `section_header`. If /// Add the new `packages` to the group file under the section `section_header`. If
/// the section header does not yet exist, it is created. The packages are written /// the section header does not yet exist, it is created. The packages are written
/// in the provided order immediately after the header. /// in the provided order immediately after the header.
///
/// # Errors
///
/// This function returns an error if the group file cannot be read, or if the
/// file cannot be written to.
pub(crate) fn save_packages(&self, section_header: &str, packages: &[Package]) -> Result<()> { pub(crate) fn save_packages(&self, section_header: &str, packages: &[Package]) -> Result<()> {
let mut content = read_to_string(&self.path) let mut content = read_to_string(&self.path)
.with_context(|| format!("reading existing file contents from {:?}", &self.path))?; .with_context(|| format!("reading existing file contents from {:?}", &self.path))?;
@@ -205,6 +221,12 @@ impl Display for Group {
} }
} }
/// Add some packages to an existing section in the content of a group file.
///
/// # Errors
///
/// This function will return an error if the header cannot be found in
/// the file content.
fn write_packages_to_existing_section( fn write_packages_to_existing_section(
group_file_content: &mut String, group_file_content: &mut String,
section_header: &str, section_header: &str,
@@ -223,6 +245,14 @@ fn write_packages_to_existing_section(
Ok(()) Ok(())
} }
/// Find the index to the first line in `group_file_content` after the
/// given `section_header`.
///
/// # Errors
///
/// This function will return an error if the `section_header` does not
/// exist in `group_file_content`, or if the line containing the
/// `section_header` is not newline-terminated.
fn find_first_package_line_in_section( fn find_first_package_line_in_section(
group_file_content: &str, group_file_content: &str,
section_header: &str, section_header: &str,
@@ -238,6 +268,7 @@ fn find_first_package_line_in_section(
Ok(section_start + distance_to_next_newline + 1) // + 1 to be after the newline Ok(section_start + distance_to_next_newline + 1) // + 1 to be after the newline
} }
/// Append a new section with some packages to the content of a group file.
fn add_new_section_with_packages( fn add_new_section_with_packages(
group_file_content: &mut String, group_file_content: &mut String,
section_header: &str, section_header: &str,
+17 -5
View File
@@ -1,13 +1,15 @@
use std::fmt::{Display, Write}; use std::fmt::{Display, Write};
use std::hash::Hash; use std::hash::Hash;
/// A struct to represent a single package, consiting of a `name`, and
/// optionally a `repo`.
#[derive(Debug, Eq, PartialOrd, Ord, Clone)] #[derive(Debug, Eq, PartialOrd, Ord, Clone)]
pub struct Package { pub struct Package {
pub(crate) name: String, pub(crate) name: String,
repo: Option<String>, repo: Option<String>,
} }
fn remove_all_but_package_name(s: &str) -> &str { fn remove_comment_and_trim_whitespace(s: &str) -> &str {
s.split('#') // remove comment s.split('#') // remove comment
.next() .next()
.expect("line contains something") .expect("line contains something")
@@ -16,7 +18,7 @@ fn remove_all_but_package_name(s: &str) -> &str {
impl From<String> for Package { impl From<String> for Package {
fn from(value: String) -> Self { fn from(value: String) -> Self {
let trimmed = remove_all_but_package_name(&value); let trimmed = remove_comment_and_trim_whitespace(&value);
debug_assert!(!trimmed.is_empty(), "empty package names are not allowed"); debug_assert!(!trimmed.is_empty(), "empty package names are not allowed");
let (name, repo) = Self::split_into_name_and_repo(trimmed); let (name, repo) = Self::split_into_name_and_repo(trimmed);
@@ -31,18 +33,28 @@ impl From<&str> for Package {
} }
impl Package { impl Package {
fn split_into_name_and_repo(s: &str) -> (String, Option<String>) { /// From a string that contains a package name, optionally prefixed by a
let mut iter = s.split('/').rev(); /// repository, return the package name as well as the repository if it
/// exists.
///
/// # Panics
///
/// Panics if `string` is empty.
fn split_into_name_and_repo(string: &str) -> (String, Option<String>) {
let mut iter = string.split('/').rev();
let name = iter.next().expect("we checked that earlier").to_string(); let name = iter.next().expect("we checked that earlier").to_string();
let repo = iter.next().map(|s| s.to_string()); let repo = iter.next().map(|s| s.to_string());
(name, repo) (name, repo)
} }
/// Try to parse a string (from a line in a group file) and return a package.
/// From the string, any possible comment is removed and whitespace is trimmed.
/// Returns `None` if there is nothing left after trimming.
pub(crate) fn try_from<S>(s: S) -> Option<Self> pub(crate) fn try_from<S>(s: S) -> Option<Self>
where where
S: AsRef<str>, S: AsRef<str>,
{ {
let trimmed = remove_all_but_package_name(s.as_ref()); let trimmed = remove_comment_and_trim_whitespace(s.as_ref());
if trimmed.is_empty() { if trimmed.is_empty() {
return None; return None;
} }