You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.8 KiB
JavaScript

import { Integer } from "../../../peg-number"
import { CommaDelimitedInteger as GroupedNumber } from "../../../peg-grouped-number"
import { Newline } from "../../../peg-newline"
import { SameLine as _ } from "../../../peg-whitespace"
import { RestOfLine, BytesValue } from "../primitives"
import { Header } from "../shared"
{
const matchValue = require("match-value");
}
RootInfo
= header:Header infoSection:InfoSection Newline* {
return { ...header, fields: infoSection }
};
InfoSection 'information section'
= "=== START OF INFORMATION SECTION ===" Newline fields:(InfoField+) {
return fields.filter((field) => field != null);
}
InfoField 'information field'
= InfoFieldSimple
/ InfoFieldIgnored
/ InfoFieldSize
/ InfoFieldRPM
/ InfoFieldSectorSizes
/ InfoFieldBoolean
/ InfoFieldUnknown
InfoFieldSimpleKey
= "Device Model" { return "model"; }
/ "Model Number" { return "model"; }
/ "Model Family" { return "modelFamily"; }
/ "Serial Number" { return "serialNumber"; }
/ "LU WWN Device Id" { return "wwn"; }
/ "Firmware Version" { return "firmwareVersion"; }
/ "Form Factor" { return "formFactor"; }
/ "ATA Version is" { return "ataVersion"; }
/ "SATA Version is" { return "sataVersion"; }
InfoFieldSimple
= key:InfoFieldSimpleKey ":" _ value:RestOfLine {
return { key: key, value: value };
}
InfoFieldUnknown
= key:$[^:]+ ":" _ RestOfLine {
console.warn(`Encountered unrecognized SMART info key: ${key}`);
return null;
}
InfoFieldIgnoredKey
= "Device is"
/ "Local Time is"
InfoFieldIgnored
= key:InfoFieldIgnoredKey ":" _ RestOfLine {
return null;
}
/ "SMART support is:" _ ("Available" / "Unavailable") RestOfLine {
// We don't actually care about this entry, but have to specify its possible values explicitly, to distinguish it from the entry we *do* care about that (annoyingly) uses the same key; see InfoFieldBoolean
return null;
}
InfoFieldSize
// NOTE: We don't actually care about the human-friendly display size after the 'bytes' specifier, hence the RestOfLine
= InfoFieldSizeKey _ value:GroupedNumber (_ "bytes")? _ RestOfLine {
return {
key: "size",
value: B(value)
};
}
InfoFieldSizeKey
= "User Capacity:"
/ "Total NVM Capacity:"
InfoFieldRPM
= "Rotation Rate:" _ value:Integer _ "rpm" Newline {
return {
key: "rpm",
value: value
};
}
InfoFieldSectorSizes
= "Sector Sizes:" _ logicalSize:BytesValue _ "bytes logical," _ physicalSize:BytesValue _ "bytes physical" Newline {
return {
key: "sectorSizes",
value: {
logical: logicalSize,
physical: physicalSize
}
};
}
InfoFieldBooleanKey
= "SMART support is" { return "smartEnabled"; }
InfoFieldBoolean
= key:InfoFieldBooleanKey ":" _ value:RestOfLine {
return {
key: key,
value: matchValue(value, {
Enabled: true,
Disabled: false
})
};
}