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
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
pub enum CheckResult {
    // Represented by a ?
    Unsupported,
    // Represented by a .
    Passed,
    // Represented by that flag's character
    Failed,
}

pub struct VerificationResult {
    pub(crate) size: CheckResult,
    pub(crate) checksum: CheckResult,
    pub(crate) major_minor: CheckResult,
    pub(crate) symbolic_link: CheckResult,
    pub(crate) owner: CheckResult,
    pub(crate) group: CheckResult,
    pub(crate) modification_time: CheckResult,
    pub(crate) is_configration: bool,
}

#[repr(u8)]
enum CheckFlags {
    Size = b'S',
    Mode = b'M',
    Checksum = b'5',
    MajorMinor = b'D',
    SymbolicLink = b'L',
    Owner = b'U',
    Group = b'G',
    ModificationTime = b'T',
}

impl VerificationResult {
    // Construct a new `VerificationResult` instance with all checks unsupported
    pub fn unknown() -> Self {
        Self {
            size: CheckResult::Unsupported,
            mode: CheckResult::Unsupported,
            checksum: CheckResult::Unsupported,
            major_minor: CheckResult::Unsupported,
            symbolic_link: CheckResult::Unsupported,
            owner: CheckResult::Unsupported,
            group: CheckResult::Unsupported,
            modification_time: CheckResult::Unsupported,
            is_configration: false,
        }
    }

    fn get_character_for_result(result: CheckResult, flag_character: char) -> char {
        if result == CheckResult::Passed {
            return '.'
        }
        if result == CheckResult::Failed {
            return flag_character
        }

        return '?'
    }

    /// Return the string representation of the check result
    ///
    /// # Examples
    /// 
    /// ```
    /// use package_file_verify::VerificationResult;
    /// let result = VerificationResult::unknown();
    /// let string = result.to_string();
    /// assert_eq!(string, "??????????")
    /// ```
    pub fn to_string() -> String {
        let mut output_string: String = "".to_owned();
     
        output_string.push_str(
            &get_character_for_result(Self.size, CheckFlags::Size).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.mode, CheckFlags::Mode).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.checksum, CheckFlags::Checksum).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.major_minor, CheckFlags::MajorMinor).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.symbolic_link, CheckFlags::SymbolicLink).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.owner, CheckFlags::Owner).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.group, CheckFlags::Group).to_string()
        );
        output_string.push_str(
            &get_character_for_result(Self.modification_time, CheckFlags::ModificationTime).to_string()
        );
        
        if Self.is_configration {
            output_string.push_str(&" c");
        }

        return output_string
    }
}