package_info: refactor sources parsing with iterator
All checks were successful
CI / build (push) Successful in 7m12s
All checks were successful
CI / build (push) Successful in 7m12s
This commit is contained in:
@@ -214,20 +214,32 @@ async fn get_components(
|
|||||||
Err("Components not found.".into())
|
Err("Components not found.".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct DebianSources {
|
||||||
* Parse a 'Sources.gz' debian package file data, to look for a target package and
|
splitted_sources: std::str::Split<'static, &'static str>,
|
||||||
* return the data for that package stanza
|
}
|
||||||
*/
|
impl DebianSources {
|
||||||
fn parse_sources(
|
fn new(data: &[u8]) -> Result<DebianSources, Box<dyn Error>> {
|
||||||
data: &[u8],
|
// Gz-decode 'Sources.gz' file into a string, and split it on stanzas
|
||||||
target_package: &str,
|
let mut d = GzDecoder::new(data);
|
||||||
target_version: Option<&str>,
|
let mut s = String::new();
|
||||||
) -> Result<Option<PackageStanza>, Box<dyn Error>> {
|
d.read_to_string(&mut s)?;
|
||||||
let mut d = GzDecoder::new(data);
|
|
||||||
let mut s = String::new();
|
|
||||||
d.read_to_string(&mut s)?;
|
|
||||||
|
|
||||||
for stanza in s.split("\n\n") {
|
// Convert the string to a static lifetime by leaking it
|
||||||
|
let static_str = Box::leak(s.into_boxed_str());
|
||||||
|
let splitted = static_str.split("\n\n");
|
||||||
|
|
||||||
|
Ok(DebianSources {
|
||||||
|
splitted_sources: splitted,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Iterator for DebianSources {
|
||||||
|
type Item = HashMap<String, String>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let stanza = self.splitted_sources.next()?;
|
||||||
|
|
||||||
|
// Parse stanza into a hashmap of strings, the fields
|
||||||
let mut fields: HashMap<String, String> = HashMap::new();
|
let mut fields: HashMap<String, String> = HashMap::new();
|
||||||
let mut current_key = String::new();
|
let mut current_key = String::new();
|
||||||
|
|
||||||
@@ -248,50 +260,62 @@ fn parse_sources(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pkg) = fields.get("Package")
|
Some(fields)
|
||||||
&& pkg == target_package
|
}
|
||||||
{
|
}
|
||||||
// Check version if requested
|
|
||||||
if let Some(ver) = target_version {
|
|
||||||
if let Some(pkg_ver) = fields.get("Version") {
|
|
||||||
if pkg_ver != ver {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut files = Vec::new();
|
/*
|
||||||
if let Some(checksums) = fields.get("Checksums-Sha256") {
|
* Parse a 'Sources.gz' debian package file data, to look for a target package and
|
||||||
for line in checksums.lines() {
|
* return the data for that package stanza
|
||||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
*/
|
||||||
if parts.len() >= 3 {
|
fn parse_sources(
|
||||||
files.push(FileEntry {
|
data: &[u8],
|
||||||
sha256: parts[0].to_string(),
|
target_package: &str,
|
||||||
size: parts[1].parse().unwrap_or(0),
|
target_version: Option<&str>,
|
||||||
name: parts[2].to_string(),
|
) -> Result<Option<PackageStanza>, Box<dyn Error>> {
|
||||||
});
|
let mut sources = DebianSources::new(data)?;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(Some(PackageStanza {
|
// Find the right package, with the right version if requested
|
||||||
package: pkg.clone(),
|
let stanza = sources.find(|s| {
|
||||||
version: fields.get("Version").cloned().unwrap_or_default(),
|
let pkg = s.get("Package");
|
||||||
directory: fields.get("Directory").cloned().unwrap_or_default(),
|
pkg.is_some()
|
||||||
format: fields
|
&& pkg.unwrap() == target_package
|
||||||
.get("Format")
|
&& (target_version.is_none() || s.get("Version").unwrap() == target_version.unwrap())
|
||||||
.cloned()
|
});
|
||||||
.unwrap_or_else(|| "1.0".to_string()),
|
|
||||||
vcs_git: fields.get("Vcs-Git").cloned(),
|
if stanza.is_none() {
|
||||||
vcs_browser: fields.get("Vcs-Browser").cloned(),
|
return Ok(None);
|
||||||
files,
|
}
|
||||||
}));
|
let stanza = stanza.unwrap();
|
||||||
|
|
||||||
|
// Parse package files
|
||||||
|
let mut files = Vec::new();
|
||||||
|
if let Some(checksums) = stanza.get("Checksums-Sha256") {
|
||||||
|
for line in checksums.lines() {
|
||||||
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
if parts.len() >= 3 {
|
||||||
|
files.push(FileEntry {
|
||||||
|
sha256: parts[0].to_string(),
|
||||||
|
size: parts[1].parse().unwrap_or(0),
|
||||||
|
name: parts[2].to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(None)
|
// Return package stanza
|
||||||
|
Ok(Some(PackageStanza {
|
||||||
|
package: stanza.get("Package").cloned().unwrap(),
|
||||||
|
version: stanza.get("Version").cloned().unwrap_or_default(),
|
||||||
|
directory: stanza.get("Directory").cloned().unwrap_or_default(),
|
||||||
|
format: stanza
|
||||||
|
.get("Format")
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| "1.0".to_string()),
|
||||||
|
vcs_git: stanza.get("Vcs-Git").cloned(),
|
||||||
|
vcs_browser: stanza.get("Vcs-Browser").cloned(),
|
||||||
|
files,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
|
|||||||
Reference in New Issue
Block a user