mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
Add Facet trait and optimize functions. Begin to structure payload information. TODO Payload string parsing FromStr
This commit is contained in:
parent
6d6cc575a4
commit
13f41862bb
4 changed files with 192 additions and 53 deletions
|
|
@ -5,12 +5,38 @@
|
|||
|
||||
use regex::{RegexSet, Regex};
|
||||
use std::collections::HashSet;
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::fs::File as OsFile;
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use failure::Error;
|
||||
use crate::payload::Payload;
|
||||
use std::clone::Clone;
|
||||
|
||||
trait FacetedAction {
|
||||
// Add a facet to the action if the facet is already present the function returns false.
|
||||
fn add_facet(&mut self, facet: Facet) -> bool;
|
||||
|
||||
// Remove a facet from the action.
|
||||
fn remove_facet(&mut self, facet: Facet) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Action {
|
||||
kind: ActionKind,
|
||||
payload_reference: String,
|
||||
properties: Vec<Property>,
|
||||
facets: HashSet<Facet>,
|
||||
}
|
||||
|
||||
impl FacetedAction for Action {
|
||||
fn add_facet(&mut self, facet: Facet) -> bool {
|
||||
return self.facets.insert(facet)
|
||||
}
|
||||
|
||||
fn remove_facet(&mut self, facet: Facet) -> bool {
|
||||
return self.facets.remove(&facet)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Dir {
|
||||
|
|
@ -23,9 +49,19 @@ pub struct Dir {
|
|||
pub facets: HashSet<Facet>,
|
||||
}
|
||||
|
||||
impl FacetedAction for Dir {
|
||||
fn add_facet(&mut self, facet: Facet) -> bool {
|
||||
return self.facets.insert(facet)
|
||||
}
|
||||
|
||||
fn remove_facet(&mut self, facet: Facet) -> bool {
|
||||
return self.facets.remove(&facet)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct File {
|
||||
pub payload: String,
|
||||
pub payload: Payload,
|
||||
pub path: String,
|
||||
pub group: String,
|
||||
pub owner: String,
|
||||
|
|
@ -39,6 +75,16 @@ pub struct File {
|
|||
pub facets: HashSet<Facet>,
|
||||
}
|
||||
|
||||
impl FacetedAction for File {
|
||||
fn add_facet(&mut self, facet: Facet) -> bool {
|
||||
return self.facets.insert(facet)
|
||||
}
|
||||
|
||||
fn remove_facet(&mut self, facet: Facet) -> bool {
|
||||
return self.facets.remove(&facet)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Hash, Eq, PartialEq, Debug, Default)]
|
||||
pub struct Facet {
|
||||
pub name: String,
|
||||
|
|
@ -75,6 +121,7 @@ impl Manifest {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ActionKind {
|
||||
Attr,
|
||||
Dir,
|
||||
|
|
@ -165,6 +212,28 @@ fn handle_manifest_line(manifest: &mut Manifest, line: &str, line_nr: usize) ->
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn add_facet_to_action<T: FacetedAction>(action: &mut T, facet_string: String, line: String, line_nr: usize) -> Result<(), ManifestError> {
|
||||
let facet_key = match facet_string.find(".") {
|
||||
Some(idx) => {
|
||||
facet_string.clone().split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("separation dot not found but string contains facet.")})?
|
||||
};
|
||||
|
||||
let value = match facet_string.find("=") {
|
||||
Some(idx) => {
|
||||
facet_string.clone().split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})?
|
||||
};
|
||||
|
||||
if !action.add_facet(Facet{name: facet_key, value}) {
|
||||
return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("double declaration of facet")})?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn determine_action_kind(line: &str) -> ActionKind {
|
||||
let mut act = String::new();
|
||||
for c in line.trim_start().chars() {
|
||||
|
|
@ -245,35 +314,21 @@ fn parse_file_action(line: String, line_nr: usize) -> Result<File, Error> {
|
|||
let key_val_string = clean_string_value(&cap[full_cap_idx]);
|
||||
|
||||
if key_val_string.contains("facet.") {
|
||||
let facet_key = match key_val_string.find(".") {
|
||||
Some(idx) => {
|
||||
key_val_string.clone().split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("separation dot not found but string contains facet.")})?
|
||||
};
|
||||
|
||||
let value = match key_val_string.find("=") {
|
||||
Some(idx) => {
|
||||
key_val_string.clone().split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})?
|
||||
};
|
||||
|
||||
if !act.facets.insert(Facet{name: facet_key, value}) {
|
||||
return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("double declaration of facet")})?
|
||||
match add_facet_to_action(&mut act, key_val_string, line, line_nr) {
|
||||
Ok(_) => continue,
|
||||
Err(e) => return Err(e)?,
|
||||
}
|
||||
|
||||
} else {
|
||||
let mut key = key_val_string.clone();
|
||||
let value = match key.find("=") {
|
||||
Some(idx) => {
|
||||
key.split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})?
|
||||
};
|
||||
key = key.replace("=", "");
|
||||
act.properties.push(Property{key, value});
|
||||
}
|
||||
|
||||
let mut key = key_val_string.clone();
|
||||
let value = match key.find("=") {
|
||||
Some(idx) => {
|
||||
key.split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})?
|
||||
};
|
||||
key = key.replace("=", "");
|
||||
act.properties.push(Property{key, value});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -300,31 +355,18 @@ fn parse_dir_action(line: String, line_nr: usize) -> Result<Dir, Error> {
|
|||
|
||||
|
||||
match &cap[key_cap_idx] {
|
||||
"path" => act.path = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""),
|
||||
"owner" => act.owner = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""),
|
||||
"group" => act.group = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""),
|
||||
"mode" => act.mode = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""),
|
||||
"revert-tag" => act.revert_tag = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""),
|
||||
"salvage-from" => act.salvage_from = String::from(&cap[val_cap_idx]).trim_end().replace(&['"', '\\'][..], ""),
|
||||
"path" => act.path = clean_string_value(&cap[val_cap_idx]),
|
||||
"owner" => act.owner = clean_string_value(&cap[val_cap_idx]),
|
||||
"group" => act.group = clean_string_value(&cap[val_cap_idx]),
|
||||
"mode" => act.mode = clean_string_value(&cap[val_cap_idx]),
|
||||
"revert-tag" => act.revert_tag = clean_string_value(&cap[val_cap_idx]),
|
||||
"salvage-from" => act.salvage_from = clean_string_value(&cap[val_cap_idx]),
|
||||
_ => {
|
||||
let key_val_string = String::from(&cap[full_cap_idx]).trim_end().replace(&['"', '\\'][..], "");
|
||||
let key_val_string = clean_string_value(&cap[full_cap_idx]);
|
||||
if key_val_string.contains("facet.") {
|
||||
let key = match key_val_string.find(".") {
|
||||
Some(idx) => {
|
||||
key_val_string.clone().split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("separation dot not found but string contains facet.")})?
|
||||
};
|
||||
|
||||
let value = match key_val_string.find("=") {
|
||||
Some(idx) => {
|
||||
key_val_string.clone().split_off(idx+1)
|
||||
},
|
||||
None => return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("no value present for facet")})?
|
||||
};
|
||||
|
||||
if !act.facets.insert(Facet{name: key, value }) {
|
||||
return Err(ManifestError::InvalidAction{action: line, line: line_nr, message: String::from("double declaration of facet")})?
|
||||
match add_facet_to_action(&mut act, key_val_string, line, line_nr) {
|
||||
Ok(_) => continue,
|
||||
Err(e) => return Err(e)?,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
46
src/digest/mod.rs
Normal file
46
src/digest/mod.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// This Source Code Form is subject to the terms of
|
||||
// the Mozilla Public License, v. 2.0. If a copy of the
|
||||
// MPL was not distributed with this file, You can
|
||||
// obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DigestAlgorithm {
|
||||
SHA1, //Default, sadly
|
||||
SHA256, //sha256t
|
||||
SHA512, //sha512t
|
||||
SHA512Half, //sha512t_256
|
||||
SHA3256, // Sha3 version of sha256t
|
||||
SHA3512Half, // Sha3 version of sha512t_256
|
||||
SHA3512, // Sha3 version of sha512t
|
||||
}
|
||||
|
||||
impl Default for DigestAlgorithm {
|
||||
fn default() -> Self { DigestAlgorithm::SHA1 }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DigestSource {
|
||||
GzipCompressed,
|
||||
GNUElf,
|
||||
GNUElfUnsigned,
|
||||
UncompressedFile
|
||||
}
|
||||
|
||||
impl Default for DigestSource {
|
||||
fn default() -> Self { DigestSource::UncompressedFile }
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Digest {
|
||||
hash: String,
|
||||
algorithm: DigestAlgorithm,
|
||||
source: DigestSource,
|
||||
}
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
pub enum DigestError {
|
||||
#[fail(display = "hashing algorithm {} is not known by this library", algorithm)]
|
||||
UnknownAlgorithm {
|
||||
algorithm: String,
|
||||
},
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
// obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
mod actions;
|
||||
mod digest;
|
||||
mod payload;
|
||||
|
||||
#[macro_use] extern crate failure;
|
||||
|
||||
|
|
|
|||
49
src/payload/mod.rs
Normal file
49
src/payload/mod.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// This Source Code Form is subject to the terms of
|
||||
// the Mozilla Public License, v. 2.0. If a copy of the
|
||||
// MPL was not distributed with this file, You can
|
||||
// obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
use crate::digest::Digest;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PayloadCompressionAlgorithm {
|
||||
Gzip,
|
||||
LZ4
|
||||
}
|
||||
|
||||
impl Default for PayloadCompressionAlgorithm {
|
||||
fn default() -> Self { PayloadCompressionAlgorithm::Gzip }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PayloadBits {
|
||||
Independent,
|
||||
Bits32,
|
||||
Bits64
|
||||
}
|
||||
|
||||
impl Default for PayloadBits {
|
||||
fn default() -> Self { PayloadBits::Independent }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PayloadArchitecture {
|
||||
NOARCH,
|
||||
I386,
|
||||
SPARC,
|
||||
ARM,
|
||||
RISCV
|
||||
}
|
||||
|
||||
impl Default for PayloadArchitecture {
|
||||
fn default() -> Self { PayloadArchitecture::NOARCH }
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Payload {
|
||||
primary_identifier: Digest,
|
||||
additional_identifiers: Vec<Digest>,
|
||||
compression_algorithm: PayloadCompressionAlgorithm,
|
||||
bitness: PayloadBits,
|
||||
architecture: PayloadArchitecture,
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue