pub mod raw;
use std::collections::HashMap;
use drivedb;
#[derive(Debug)]
#[cfg_attr(feature = "serializable", derive(Serialize))]
pub struct SmartAttribute {
pub id: u8,
pub name: Option<String>,
pub pre_fail: bool, pub online: bool,
pub performance: bool,
pub error_rate: bool,
pub event_count: bool,
pub self_preserving: bool,
pub flags: u16,
pub value: Option<u8>,
pub worst: Option<u8>,
pub raw: raw::Raw,
pub thresh: Option<u8>, }
pub fn parse_smart_values(data: &Vec<u8>, raw_thresh: &Vec<u8>, meta: &Option<drivedb::DriveMeta>) -> Vec<SmartAttribute> {
let mut threshs = HashMap::<u8, u8>::new();
for i in 0..30 {
let offset = 2 + i * 12;
if raw_thresh[offset] == 0 { continue } threshs.insert(raw_thresh[offset], raw_thresh[offset+1]);
}
let mut attrs = vec![];
for i in 0..30 {
let offset = 2 + i * 12;
if data[offset] == 0 { continue }
let flags = (data[offset + 1] as u16) + ((data[offset + 2] as u16) << 8);
let id = data[offset];
let attr = meta.as_ref().map(|meta| meta.render_attribute(id)).unwrap_or(None);
let is_in_raw = |c| attr.as_ref().map(|a| a.byte_order.contains(c)).unwrap_or(false);
attrs.push(SmartAttribute {
id: id,
name: match attr {
Some(ref a) => a.name.clone(),
None => None
},
pre_fail: flags & (1<<0) != 0,
online: flags & (1<<1) != 0,
performance: flags & (1<<2) != 0,
error_rate: flags & (1<<3) != 0,
event_count: flags & (1<<4) != 0,
self_preserving: flags & (1<<5) != 0,
flags: flags & (!0b11_1111),
value: if !is_in_raw('v') {
Some(data[offset + 3])
} else { None },
worst: if !is_in_raw('w') {
Some(data[offset + 4])
} else { None },
raw: raw::Raw::from_raw_entry(&data[offset .. offset + 12], &attr),
thresh: threshs.get(&data[offset]).map(|t| *t),
})
}
attrs
}