1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! RPM database access
//!
//! The database used is whichever one is configured as the `_dbpath` in the
//! in the global macro context. By default this is unset: you will need to
//! call `librpm::config::read_file(None)` to read the default "rpmrc"
//! configuration.
//!
//! # Example
//!
//! Finding the "rpm-devel" RPM in the database:
//!
//! ```
//! use librpm::Index;
//!
//! librpm::config::read_file(None).unwrap();
//!
//! let mut matches = Index::Name.find("rpm-devel");
//! let package = matches.next().unwrap();
//!
//! println!("package name: {}", package.name);
//! println!("package summary: {}", package.summary);
//! println!("package version: {}", package.version);
//! ```

use streaming_iterator::StreamingIterator;

use internal::{iterator::MatchIterator, tag::Tag};
use package::Package;

/// Iterator over the RPM database which returns `Package` structs.
pub struct Iter(MatchIterator);

impl Iterator for Iter {
    type Item = Package;

    /// Obtain the next header from the iterator.
    fn next(&mut self) -> Option<Package> {
        self.0.next().map(|h| h.to_package())
    }
}

/// Searchable fields in the RPM package headers.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Index {
    /// Search by package name.
    Name,

    /// Search by package version.
    Version,

    /// Search by package license.
    License,

    /// Search by package summary.
    Summary,

    /// Search by package description.
    Description,
}

impl Index {
    /// Find an exact match in the given index
    pub fn find<S: AsRef<str>>(self, key: S) -> Iter {
        Iter(MatchIterator::new(self.into(), Some(key.as_ref())))
    }
}

impl Into<Tag> for Index {
    fn into(self) -> Tag {
        match self {
            Index::Name => Tag::NAME,
            Index::Version => Tag::VERSION,
            Index::License => Tag::LICENSE,
            Index::Summary => Tag::SUMMARY,
            Index::Description => Tag::DESCRIPTION,
        }
    }
}

/// Find all packages installed on the local system.
pub fn installed_packages() -> Iter {
    Iter(MatchIterator::new(Tag::NAME, None))
}

/// Find installed packages with a search key that exactly matches the given tag.
///
/// Panics if the glob contains null bytes.
pub fn find<S: AsRef<str>>(index: Index, key: S) -> Iter {
    index.find(key)
}